Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Addresses issue #24618 "Road sign" boxstyle/annotation, alternative to #24697#24744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
Abitamim wants to merge5 commits intomatplotlib:main
base:main
Choose a base branch
Loading
fromAbitamim:adjustable-arrow-head-annotation
Draft
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 84 additions & 8 deletionslib/matplotlib/patches.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This can be done asself.head_width = np.clip(head_width, 0, 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
Expand All@@ -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)
Expand All@@ -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
Expand All@@ -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)
Expand Down
Loading
Sorry, something went wrong.Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletionslib/matplotlib/tests/test_arrow_patches.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,6 +48,29 @@ def test_boxarrow():
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():
"""
Convenience function that prepares and returns a FancyArrowPatch. It aims
Expand Down
10 changes: 5 additions & 5 deletionstutorials/text/annotations.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand DownExpand Up@@ -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))
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp