Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 61661ab

Browse files
authored
Merge pull request #27692 from saranti/update_arrow
Add method to update position of arrow patch
2 parents 44fd352 + 659fec8 commit 61661ab

File tree

4 files changed

+101
-7
lines changed

4 files changed

+101
-7
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Update the position of arrow patch
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
Adds a setter method that allows the user to update the position of the
4+
`.patches.Arrow` object without requiring a full re-draw.
5+
6+
.. plot::
7+
:include-source: true
8+
:alt: Example of changing the position of the arrow with the new ``set_data`` method.
9+
10+
import matplotlib as mpl
11+
import matplotlib.pyplot as plt
12+
from matplotlib.patches import Arrow
13+
import matplotlib.animation as animation
14+
15+
fig, ax = plt.subplots()
16+
ax.set_xlim(0, 10)
17+
ax.set_ylim(0, 10)
18+
19+
a = mpl.patches.Arrow(2, 0, 0, 10)
20+
ax.add_patch(a)
21+
22+
23+
# code for modifying the arrow
24+
def update(i):
25+
a.set_data(x=.5, dx=i, dy=6, width=2)
26+
27+
28+
ani = animation.FuncAnimation(fig, update, frames=15, interval=90, blit=False)
29+
30+
plt.show()

lib/matplotlib/patches.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,19 +1297,47 @@ def __init__(self, x, y, dx, dy, *, width=1.0, **kwargs):
12971297
properties.
12981298
"""
12991299
super().__init__(**kwargs)
1300-
self._patch_transform = (
1301-
transforms.Affine2D()
1302-
.scale(np.hypot(dx, dy), width)
1303-
.rotate(np.arctan2(dy, dx))
1304-
.translate(x, y)
1305-
.frozen())
1300+
self.set_data(x, y, dx, dy, width)
13061301

13071302
def get_path(self):
13081303
return self._path
13091304

13101305
def get_patch_transform(self):
13111306
return self._patch_transform
13121307

1308+
def set_data(self, x=None, y=None, dx=None, dy=None, width=None):
1309+
"""
1310+
Set `.Arrow` x, y, dx, dy and width.
1311+
Values left as None will not be updated.
1312+
1313+
Parameters
1314+
----------
1315+
x, y : float or None, default: None
1316+
The x and y coordinates of the arrow base.
1317+
1318+
dx, dy : float or None, default: None
1319+
The length of the arrow along x and y direction.
1320+
1321+
width : float or None, default: None
1322+
Width of full arrow tail.
1323+
"""
1324+
if x is not None:
1325+
self._x = x
1326+
if y is not None:
1327+
self._y = y
1328+
if dx is not None:
1329+
self._dx = dx
1330+
if dy is not None:
1331+
self._dy = dy
1332+
if width is not None:
1333+
self._width = width
1334+
self._patch_transform = (
1335+
transforms.Affine2D()
1336+
.scale(np.hypot(self._dx, self._dy), self._width)
1337+
.rotate(np.arctan2(self._dy, self._dx))
1338+
.translate(self._x, self._y)
1339+
.frozen())
1340+
13131341

13141342
class FancyArrow(Polygon):
13151343
"""

lib/matplotlib/patches.pyi

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,14 @@ class Arrow(Patch):
181181
def __init__(
182182
self, x: float, y: float, dx: float, dy: float, *, width: float = ..., **kwargs
183183
) -> None: ...
184-
184+
def set_data(
185+
self,
186+
x: float | None = ...,
187+
y: float | None = ...,
188+
dx: float | None = ...,
189+
dy: float | None = ...,
190+
width: float | None = ...,
191+
) -> None: ...
185192
class FancyArrow(Polygon):
186193
def __init__(
187194
self,

lib/matplotlib/tests/test_patches.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,3 +931,32 @@ def test_modifying_arc(fig_test, fig_ref):
931931
fig_test.subplots().add_patch(arc2)
932932
arc2.set_width(.5)
933933
arc2.set_angle(20)
934+
935+
936+
def test_arrow_set_data():
937+
fig, ax = plt.subplots()
938+
arrow = mpl.patches.Arrow(2, 0, 0, 10)
939+
expected1 = np.array(
940+
[[1.9, 0.],
941+
[2.1, -0.],
942+
[2.1, 8.],
943+
[2.3, 8.],
944+
[2., 10.],
945+
[1.7, 8.],
946+
[1.9, 8.],
947+
[1.9, 0.]]
948+
)
949+
assert np.allclose(expected1, np.round(arrow.get_verts(), 2))
950+
951+
expected2 = np.array(
952+
[[0.39, 0.04],
953+
[0.61, -0.04],
954+
[3.01, 6.36],
955+
[3.24, 6.27],
956+
[3.5, 8.],
957+
[2.56, 6.53],
958+
[2.79, 6.44],
959+
[0.39, 0.04]]
960+
)
961+
arrow.set_data(x=.5, dx=3, dy=8, width=1.2)
962+
assert np.allclose(expected2, np.round(arrow.get_verts(), 2))

0 commit comments

Comments
 (0)