From e1241a3a08c14026e186922c352e57d0830e3491 Mon Sep 17 00:00:00 2001 From: Abitamim Bharmal Date: Thu, 15 Dec 2022 23:07:31 -0500 Subject: [PATCH 1/4] Make arrow annotation arrowhead adjustable --- lib/matplotlib/patches.py | 92 +++++++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index d6a25dfc487c..edd669f9852b 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -2372,14 +2372,35 @@ def __call__(self, x0, y0, width, height, mutation_size): class LArrow: """A box in the shape of a left-pointing arrow.""" - def __init__(self, pad=0.3): + def __init__(self, pad=0.3, head_width=1.5, head_angle=90.0): """ Parameters ---------- pad : float, default: 0.3 The amount of padding around the original box. + head_width : float, default: 1.5 + The width of the arrow head versus the body. The minimum value + is 0.0 and the maximum value is 10.0. Any value smaller or + greater than this is contrained to the edge values. + head_angle : float, default: 90.0 + The inside angle of the tip of the arrow. The minimum value is + 10.0 and the maximum value is 179.0. Any value smaller or + greater than this is contrained to the edge values. """ self.pad = pad + if head_width > 10: + self.head_width = 10 + elif head_width < 0: + self.head_width = 0 + else: + self.head_width = head_width + + if head_angle >= 180: + self.head_angle = 179 + elif head_angle < 10: + self.head_angle = 10 + else: + self.head_angle = head_angle def __call__(self, x0, y0, width, height, mutation_size): # padding @@ -2394,10 +2415,26 @@ def __call__(self, x0, y0, width, height, mutation_size): dxx = dx / 2 x0 = x0 + pad / 1.4 # adjust by ~sqrt(2) + # The width adjustment is the value that must be added or + # subtracted from y_0 and y_1 for the ends of the head. + # The body width is 2dx. + # Subtracting 1 from the head_width gives what percentage of the + # body width is in the head, and there is .5x of that on each side. + # The .5 cancels out the 2dx for the body width. + width_adjustment = (self.head_width - 1) * dx + + # The angle adjustment is the value that must be subtracted/added + # from x_0 or x_1 for the position of the tip. + # each half of the arrow head is a right angle triangle. Therefore, + # each half of the arrow head has the equation tan(head_angle/2)= + # (dx+width_adjustment)/(dxx+angle_adjustment). + angle_adjustment = ((dx + width_adjustment) / math.tan((self. + head_angle/2) * (math.pi/180))) - dxx + return Path._create_closed( [(x0 + dxx, y0), (x1, y0), (x1, y1), (x0 + dxx, y1), - (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx), - (x0 + dxx, y0 - dxx), # arrow + (x0 + dxx, y1 + width_adjustment), (x0 - angle_adjustment, y0 + + dx), (x0 + dxx, y0 - width_adjustment), # arrow (x0 + dxx, y0)]) @_register_style(_style_list) @@ -2415,14 +2452,35 @@ class DArrow: """A box in the shape of a two-way arrow.""" # Modified from LArrow to add a right arrow to the bbox. - def __init__(self, pad=0.3): + def __init__(self, pad=0.3, head_width=1.5, head_angle=90.0): """ Parameters ---------- pad : float, default: 0.3 The amount of padding around the original box. + head_width : float, default: 1.5 + The width of the arrow head versus the body. The minimum value + is 0.0 and the maximum value is 10.0. Any value smaller or + greater than this is contrained to the edge values. + head_angle : float, default: 90.0 + The inside angle of the tip of the arrow. The minimum value is + 10.0 and the maximum value is 179.0. Any value smaller or + greater than this is contrained to the edge values. """ self.pad = pad + if head_width > 10: + self.head_width = 10 + elif head_width < 0: + self.head_width = 0 + else: + self.head_width = head_width + + if head_angle >= 180: + self.head_angle = 179 + elif head_angle < 10: + self.head_angle = 10 + else: + self.head_angle = head_angle def __call__(self, x0, y0, width, height, mutation_size): # padding @@ -2438,13 +2496,31 @@ def __call__(self, x0, y0, width, height, mutation_size): dxx = dx / 2 x0 = x0 + pad / 1.4 # adjust by ~sqrt(2) + # The width adjustment is the value that must be added or + # subtracted from y_0 and y_1 for the ends of the head. + # The body width is 2dx. + # Subtracting 1 from the head_width gives what percentage of the + # body width is in the head, and there is .5x of that on each side. + # The .5 cancels out the 2dx for the body width. + width_adjustment = (self.head_width - 1) * dx + + # The angle adjustment is the value that must be subtracted/added + # from x_0 or x_1 for the position of the tip. + # each half of the arrow head is a right angle triangle. Therefore, + # each half of the arrow head has the equation tan(head_angle/2)= + # (dx+width_adjustment)/(dxx+angle_adjustment). + angle_adjustment = ((dx + width_adjustment) / math.tan((self. + head_angle/2) * (math.pi/180))) - dxx + return Path._create_closed([ (x0 + dxx, y0), (x1, y0), # bot-segment - (x1, y0 - dxx), (x1 + dx + dxx, y0 + dx), - (x1, y1 + dxx), # right-arrow + (x1, y0 - width_adjustment), + (x1 + angle_adjustment + dxx, y0 + dx), + (x1, y1 + width_adjustment), # right-arrow (x1, y1), (x0 + dxx, y1), # top-segment - (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx), - (x0 + dxx, y0 - dxx), # left-arrow + (x0 + dxx, y1 + width_adjustment), + (x0 - angle_adjustment, y0 + dx), + (x0 + dxx, y0 - width_adjustment), # left-arrow (x0 + dxx, y0)]) @_register_style(_style_list) From 792c229aca59b655c7c4e46126ae8179bc5de79b Mon Sep 17 00:00:00 2001 From: Abitamim Bharmal Date: Thu, 15 Dec 2022 23:07:42 -0500 Subject: [PATCH 2/4] Add test - not sure if correct --- .../roadsign_test_image.png | Bin 0 -> 10660 bytes lib/matplotlib/tests/test_arrow_patches.py | 21 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 lib/matplotlib/tests/baseline_images/test_arrow_patches/roadsign_test_image.png diff --git a/lib/matplotlib/tests/baseline_images/test_arrow_patches/roadsign_test_image.png b/lib/matplotlib/tests/baseline_images/test_arrow_patches/roadsign_test_image.png new file mode 100644 index 0000000000000000000000000000000000000000..d9cf3646b5857078f0df436313c15f3bd78a81fe GIT binary patch literal 10660 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 B6f^(; literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_arrow_patches.py b/lib/matplotlib/tests/test_arrow_patches.py index 8d573b4adb1b..9d38111b19ff 100644 --- a/lib/matplotlib/tests/test_arrow_patches.py +++ b/lib/matplotlib/tests/test_arrow_patches.py @@ -47,6 +47,27 @@ def test_boxarrow(): transform=fig.transFigure, bbox=dict(boxstyle=stylename, fc="w", ec="k")) +@image_comparison(['roadsign_test_image.png']) +def temp_test_boxarrow(): + + styles = mpatches.BoxStyle.get_styles() + + n = len(styles) + spacing = 1.2 + + figheight = (n * spacing + .5) + fig = plt.figure(figsize=(4 / 1.5, figheight / 1.5)) + + fontsize = 0.3 * 72 + + for i, stylename in enumerate(sorted(styles)): + if stylename in ("larrow", "rarrow", "darrow"): + fig.text(0.5, ((n - i) * spacing - 0.5)/figheight, stylename, + ha="center", + size=fontsize, + transform=fig.transFigure, + bbox=dict(boxstyle=stylename+",head_width=1", fc="w", ec="k")) + def __prepare_fancyarrow_dpi_cor_test(): """ From 0e890ece5cdf638b2cad1554fb9f16d97968f7bd Mon Sep 17 00:00:00 2001 From: Abitamim Bharmal Date: Thu, 15 Dec 2022 23:14:49 -0500 Subject: [PATCH 3/4] Update tutorial --- tutorials/text/annotations.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tutorials/text/annotations.py b/tutorials/text/annotations.py index bee2e244238d..8cb1239e56c8 100644 --- a/tutorials/text/annotations.py +++ b/tutorials/text/annotations.py @@ -192,10 +192,10 @@ # Class Name Attrs # ========== ============== ========================== # Circle ``circle`` pad=0.3 -# DArrow ``darrow`` pad=0.3 +# DArrow ``darrow`` pad=0.3,head_width=1.5,head_angle=90 # Ellipse ``ellipse`` pad=0.3 -# LArrow ``larrow`` pad=0.3 -# RArrow ``rarrow`` pad=0.3 +# LArrow ``larrow`` pad=0.3,head_width=1.5,head_angle=90 +# RArrow ``rarrow`` pad=0.3,head_width=1.5,head_angle=90 # Round ``round`` pad=0.3,rounding_size=None # Round4 ``round4`` pad=0.3,rounding_size=None # Roundtooth ``roundtooth`` pad=0.3,tooth_size=None @@ -254,8 +254,8 @@ def custom_box_style(x0, y0, width, height, mutation_size): x0, y0 = x0 - pad, y0 - pad x1, y1 = x0 + width, y0 + height # return the new path - return Path([(x0, y0), (x1, y0), (x1, y1), (x0, y1), - (x0-pad, (y0+y1)/2), (x0, y0), (x0, y0)], + return Path([(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y1-pad), + (x0-pad, (y0+y1)/2), (x0, y0+pad), (x0, y0), (x0, y0)], closed=True) fig, ax = plt.subplots(figsize=(3, 3)) From 94907fe2dd17a5e2dd8c0d04efd60816653dc63f Mon Sep 17 00:00:00 2001 From: Abitamim Bharmal Date: Thu, 15 Dec 2022 23:44:37 -0500 Subject: [PATCH 4/4] Fixed linting --- lib/matplotlib/tests/test_arrow_patches.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/tests/test_arrow_patches.py b/lib/matplotlib/tests/test_arrow_patches.py index 9d38111b19ff..bf71bc4a674c 100644 --- a/lib/matplotlib/tests/test_arrow_patches.py +++ b/lib/matplotlib/tests/test_arrow_patches.py @@ -47,6 +47,7 @@ def test_boxarrow(): transform=fig.transFigure, bbox=dict(boxstyle=stylename, fc="w", ec="k")) + @image_comparison(['roadsign_test_image.png']) def temp_test_boxarrow(): @@ -63,10 +64,11 @@ def temp_test_boxarrow(): for i, stylename in enumerate(sorted(styles)): if stylename in ("larrow", "rarrow", "darrow"): fig.text(0.5, ((n - i) * spacing - 0.5)/figheight, stylename, - ha="center", - size=fontsize, - transform=fig.transFigure, - bbox=dict(boxstyle=stylename+",head_width=1", fc="w", ec="k")) + ha="center", + size=fontsize, + transform=fig.transFigure, + bbox=dict(boxstyle=stylename+",head_width=1", fc="w", + ec="k")) def __prepare_fancyarrow_dpi_cor_test():