8000 Merge pull request #19460 from QuLogic/bracket-angle · matplotlib/matplotlib@d57a457 · GitHub
[go: up one dir, main page]

Skip to content

Commit d57a457

Browse files
authored
Merge pull request #19460 from QuLogic/bracket-angle
ENH: Implement angles for bracket arrow styles.
2 parents 73b5101 + 0d42d1e commit d57a457

File tree

4 files changed

+66
-10
lines changed

4 files changed

+66
-10
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Angles on Bracket arrow styles
2+
------------------------------
3+
4+
Angles specified on the *Bracket* arrow styles (``]-[``, ``]-``, ``-[``, or
5+
``|-|`` passed to *arrowstyle* parameter of `.FancyArrowPatch`) are now
6+
applied. Previously, the *angleA* and *angleB* options were allowed, but did
7+
nothing.
8+
9+
.. plot::
10+
11+
import matplotlib.pyplot as plt
12+
import matplotlib.patches as mpatches
13+
14+
fig, ax = plt.subplots()
15+
ax.set(xlim=(0, 1), ylim=(-1, 4))
16+
17+
for i, stylename in enumerate((']-[', '|-|')):
18+
for j, angle in enumerate([-30, 60]):
19+
arrowstyle = f'{stylename},angleA={angle},angleB={-angle}'
20+
patch = mpatches.FancyArrowPatch((0.1, 2*i + j), (0.9, 2*i + j),
21+
arrowstyle=arrowstyle,
22+
mutation_scale=25)
23+
ax.text(0.5, 2*i + j, arrowstyle,
24+
verticalalignment='bottom', horizontalalignment='center')
25+
ax.add_patch(patch)

lib/matplotlib/patches.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3207,7 +3207,7 @@ def __init__(self, bracketA=None, bracketB=None,
32073207
self.scaleA, self.scaleB = scaleA, scaleB
32083208

32093209
def _get_bracket(self, x0, y0,
3210-
cos_t, sin_t, width, length):
3210+
cos_t, sin_t, width, length, angle):
32113211

32123212
# arrow from x0, y0 to x1, y1
32133213
from matplotlib.bezier import get_normal_points
@@ -3224,6 +3224,10 @@ def _get_bracket(self, x0, y0,
32243224
Path.LINETO,
32253225
Path.LINETO]
32263226

3227+
if angle is not None:
3228+
trans = transforms.Affine2D().rotate_deg_around(x0, y0, angle)
3229+
vertices_arrow = trans.transform(vertices_arrow)
3230+
32273231
return vertices_arrow, codes_arrow
32283232

32293233
def transmute(self, path, mutation_size, linewidth):
@@ -3246,7 +3250,8 @@ def transmute(self, path, mutation_size, linewidth):
32463250
cos_t, sin_t = get_cos_sin(x1, y1, x0, y0)
32473251
verticesA, codesA = self._get_bracket(x0, y0, cos_t, sin_t,
32483252
self.widthA * scaleA,
3249-
self.lengthA * scaleA)
3253+
self.lengthA * scaleA,
3254+
self.angleA)
32503255
vertices_list.append(verticesA)
32513256
codes_list.append(codesA)
32523257

@@ -3259,7 +3264,8 @@ def transmute(self, path, mutation_size, linewidth):
32593264
cos_t, sin_t = get_cos_sin(x1, y1, x0, y0)
32603265
verticesB, codesB = self._get_bracket(x0, y0, cos_t, sin_t,
32613266
self.widthB * scaleB,
3262-
self.lengthB * scaleB)
3267+
self.lengthB * scaleB,
3268+
self.angleB)
32633269
vertices_list.append(verticesB)
32643270
codes_list.append(codesB)
32653271

@@ -3287,7 +3293,9 @@ def __init__(self,
32873293
Length of the bracket.
32883294
32893295
angleA : float, default: None
3290-
Angle between the bracket and the line.
3296+
Angle, in degrees, between the bracket and the line. Zero is
3297+
perpendicular to the line, and positive measures
3298+
counterclockwise.
32913299
32923300
widthB : float, default: 1.0
32933301
Width of the bracket.
@@ -3296,7 +3304,9 @@ def __init__(self,
32963304
Length of the bracket.
32973305
32983306
angleB : float, default: None
3299-
Angle between the bracket and the line.
3307+
Angle, in degrees, between the bracket and the line. Zero is
3308+
perpendicular to the line, and positive measures
3309+
counterclockwise.
33003310
"""
33013311
super().__init__(True, True,
33023312
widthA=widthA, lengthA=lengthA, angleA=angleA,
@@ -3337,7 +3347,9 @@ def __init__(self, widthB=1., lengthB=0.2, angleB=None):
33373347
Length of the bracket.
33383348
33393349
angleB : float, default: None
3340-
Angle between the bracket and the line.
3350+
Angle, in degrees, between the bracket and the line. Zero is
3351+
perpendicular to the line, and positive measures
3352+
counterclockwise.
33413353
"""
33423354
super().__init__(None, True,
33433355
widthB=widthB, lengthB=lengthB, angleB=angleB)
@@ -3356,13 +3368,17 @@ def __init__(self,
33563368
Width of the bracket.
33573369
33583370
angleA : float, default: None
3359-
Angle between the bracket and the line.
3371+
Angle, in degrees, between the bracket and the line. Zero is
3372+
perpendicular to the line, and positive measures
3373+
counterclockwise.
33603374
33613375
widthB : float, default: 1.0
33623376
Width of the bracket.
33633377
33643378
angleB : float, default: None
3365-
Angle between the bracket and the line.
3379+
Angle, in degrees, between the bracket and the line. Zero is
3380+
perpendicular to the line, and positive measures
3381+
counterclockwise.
33663382
"""
33673383
super().__init__(True, True,
33683384
widthA=widthA, lengthA=0, angleA=angleA,
Loading

lib/matplotlib/tests/test_arrow_patches.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,31 @@ def test_arrow_styles():
119119
styles = mpatches.ArrowStyle.get_styles()
120120

121121
n = len(styles)
122-
fig, ax = plt.subplots(figsize=(6, 10))
122+
fig, ax = plt.subplots(figsize=(8, 8))
123123
ax.set_xlim(0, 1)
124124
ax.set_ylim(-1, n)
125+
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
125126

126127
for i, stylename in enumerate(sorted(styles)):
127-
patch = mpatches.FancyArrowPatch((0.1, i), (0.8, i),
128+
patch = mpatches.FancyArrowPatch((0.1, i), (0.45, i),
128129
arrowstyle=stylename,
129130
mutation_scale=25)
130131
ax.add_patch(patch)
131132

133+
for i, stylename in enumerate([']-[', ']-', '-[', '|-|']):
134+
style = stylename
135+
if stylename[0] != '-':
136+
style += ',angleA=ANGLE'
137+
if stylename[-1] != '-':
138+
style += ',angleB=ANGLE'
139+
140+
for j, angle in enumerate([-30, 60]):
141+
arrowstyle = style.replace('ANGLE', str(angle))
142+
patch = mpatches.FancyArrowPatch((0.55, 2*i + j), (0.9, 2*i + j),
143+
arrowstyle=arrowstyle,
144+
mutation_scale=25)
145+
ax.add_patch(patch)
146+
132147

133148
@image_comparison(['connection_styles.png'], style='mpl20', remove_text=True)
134149
def test_connection_styles():

0 commit comments

Comments
 (0)
0