Skip to content

Commit be5aadb

Browse files
jacoverstermeeseeksmachine
authored andcommitted
Backport PR #24145: Updated Angles on Bracket arrow styles example to make angles clear #23176
1 parent 0f29958 commit be5aadb

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
===================================
3+
Angle annotations on bracket arrows
4+
===================================
5+
6+
This example shows how to add angle annotations to bracket arrow styles
7+
created using `.FancyArrowPatch`. *angleA* and *angleB* are measured from a
8+
vertical line as positive (to the left) or negative (to the right). Blue
9+
`.FancyArrowPatch` arrows indicate the directions of *angleA* and *angleB*
10+
from the vertical and axes text annotate the angle sizes.
11+
"""
12+
13+
import matplotlib.pyplot as plt
14+
import numpy as np
15+
from matplotlib.patches import FancyArrowPatch
16+
17+
18+
def get_point_of_rotated_vertical(origin, line_length, degrees):
19+
"""Return xy coordinates of the vertical line end rotated by degrees."""
20+
rad = np.deg2rad(-degrees)
21+
return [origin[0] + line_length * np.sin(rad),
22+
origin[1] + line_length * np.cos(rad)]
23+
24+
25+
fig, ax = plt.subplots(figsize=(8, 7))
26+
ax.set(xlim=(0, 6), ylim=(-1, 4))
27+
ax.set_title("Orientation of the bracket arrows relative to angleA and angleB")
28+
29+
for i, style in enumerate(["]-[", "|-|"]):
30+
for j, angle in enumerate([-40, 60]):
31+
y = 2*i + j
32+
arrow_centers = ((1, y), (5, y))
33+
vlines = ((1, y + 0.5), (5, y + 0.5))
34+
anglesAB = (angle, -angle)
35+
bracketstyle = f"{style}, angleA={anglesAB[0]}, angleB={anglesAB[1]}"
36+
bracket = FancyArrowPatch(*arrow_centers, arrowstyle=bracketstyle,
37+
mutation_scale=42)
38+
ax.add_patch(bracket)
39+
ax.text(3, y + 0.05, bracketstyle, ha="center", va="bottom")
40+
ax.vlines([i[0] for i in vlines], [y, y], [i[1] for i in vlines],
41+
linestyles="--", color="C0")
42+
# Get the top coordinates for the drawn patches at A and B
43+
patch_tops = [get_point_of_rotated_vertical(center, 0.5, angle)
44+
for center, angle in zip(arrow_centers, anglesAB)]
45+
# Define the connection directions for the annotation arrows
46+
connection_dirs = (1, -1) if angle > 0 else (-1, 1)
47+
# Add arrows and annotation text
48+
arrowstyle = "Simple, tail_width=0.5, head_width=4, head_length=8"
49+
for vline, dir, patch_top, angle in zip(vlines, connection_dirs,
50+
patch_tops, anglesAB):
51+
kw = dict(connectionstyle=f"arc3,rad={dir * 0.5}",
52+
arrowstyle=arrowstyle, color="C0")
53+
ax.add_patch(FancyArrowPatch(vline, patch_top, **kw))
54+
ax.text(vline[0] - dir * 0.15, y + 0.3, f'{angle}°', ha="center",
55+
va="center")
56+
57+
#############################################################################
58+
#
59+
# .. admonition:: References
60+
#
61+
# The use of the following functions, methods, classes and modules is shown
62+
# in this example:
63+
#
64+
# - `matplotlib.patches.ArrowStyle`

lib/matplotlib/patches.py

+8
Original file line numberDiff line numberDiff line change
@@ -3119,6 +3119,14 @@ class ArrowStyle(_Style):
31193119
stroked. This is meant to be used to correct the location of the
31203120
head so that it does not overshoot the destination point, but not all
31213121
classes support it.
3122+
3123+
Notes
3124+
-----
3125+
*angleA* and *angleB* specify the orientation of the bracket, as either a
3126+
clockwise or counterclockwise angle depending on the arrow type. 0 degrees
3127+
means perpendicular to the line connecting the arrow's head and tail.
3128+
3129+
.. plot:: gallery/text_labels_and_annotations/angles_on_bracket_arrows.py
31223130
"""
31233131

31243132
_style_list = {}

0 commit comments

Comments
 (0)