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

Skip to content

Commit c511628

Browse files
authored
Merge pull request #7719 from dstansby/quiverkey-angle
[MRG+1] Add angle kwarg to quiverkey
2 parents a430bf2 + e78445a commit c511628

File tree

4 files changed

+36
-10
lines changed

4 files changed

+36
-10
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
New quiverkey angle kwarg
2+
-------------------------
3+
4+
Plotting a :func:`quiverkey` now admits the ``angle`` kwarg,
5+
which sets the angle at which to draw the key arrow.

lib/matplotlib/quiver.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@
185185
186186
Keyword arguments:
187187
188+
*angle* = 0
189+
The angle of the key arrow. Measured in degrees anti-clockwise from the
190+
x-axis.
191+
188192
*coordinates* = [ 'axes' | 'figure' | 'data' | 'inches' ]
189193
Coordinate system and units for *X*, *Y*: 'axes' and 'figure' are
190194
normalized coordinate systems with 0,0 in the lower left and 1,1
@@ -236,6 +240,7 @@ def __init__(self, Q, X, Y, U, label, **kw):
236240
self.X = X
237241
self.Y = Y
238242
self.U = U
243+
self.angle = kw.pop('angle', 0)
239244
self.coord = kw.pop('coordinates', 'axes')
240245
self.color = kw.pop('color', None)
241246
self.label = label
@@ -296,7 +301,8 @@ def _init(self):
296301
_mask = self.Q.Umask
297302
self.Q.Umask = ma.nomask
298303
self.verts = self.Q._make_verts(np.array([self.U]),
299-
np.zeros((1,)))
304+
np.zeros((1,)),
305+
self.angle)
300306
self.Q.Umask = _mask
301307
self.Q.pivot = _pivot
302308
kw = self.Q.polykw
@@ -514,7 +520,7 @@ def _init(self):
514520

515521
# _make_verts sets self.scale if not already specified
516522
if not self._initialized and self.scale is None:
517-
self._make_verts(self.U, self.V)
523+
self._make_verts(self.U, self.V, self.angles)
518524

519525
self._initialized = True
520526

@@ -530,7 +536,7 @@ def get_datalim(self, transData):
530536
@allow_rasterization
531537
def draw(self, renderer):
532538
self._init()
533-
verts = self._make_verts(self.U, self.V)
539+
verts = self._make_verts(self.U, self.V, self.angles)
534540
self.set_verts(verts, closed=False)
535541
self._new_UV = False
536542
mcollections.PolyCollection.draw(self, renderer)
@@ -610,15 +616,15 @@ def _angles_lengths(self, U, V, eps=1):
610616
lengths = np.hypot(*dxy.T) / eps
611617
return angles, lengths
612618

613-
def _make_verts(self, U, V):
619+
def _make_verts(self, U, V, angles):
614620
uv = (U + V * 1j)
615-
str_angles = isinstance(self.angles, six.string_types)
616-
if str_angles and (self.angles == 'xy' and self.scale_units == 'xy'):
621+
str_angles = isinstance(angles, six.string_types)
622+
if str_angles and (angles == 'xy' and self.scale_units == 'xy'):
617623
# Here eps is 1 so that if we get U, V by diffing
618624
# the X, Y arrays, the vectors will connect the
619625
# points, regardless of the axis scaling (including log).
620626
angles, lengths = self._angles_lengths(U, V, eps=1)
621-
elif str_angles and (self.angles == 'xy' or self.scale_units == 'xy'):
627+
elif str_angles and (angles == 'xy' or self.scale_units == 'xy'):
622628
# Calculate eps based on the extents of the plot
623629
# so that we don't end up with roundoff error from
624630
# adding a small number to a large.
@@ -651,12 +657,12 @@ def _make_verts(self, U, V):
651657
self.scale = scale * widthu_per_lenu
652658
length = a * (widthu_per_lenu / (self.scale * self.width))
653659
X, Y = self._h_arrows(length)
654-
if str_angles and (self.angles == 'xy'):
660+
if str_angles and (angles == 'xy'):
655661
theta = angles
656-
elif str_angles and (self.angles == 'uv'):
662+
elif str_angles and (angles == 'uv'):
657663
theta = np.angle(uv)
658664
else:
659-
theta = ma.masked_invalid(np.deg2rad(self.angles)).filled(0)
665+
theta = ma.masked_invalid(np.deg2rad(angles)).filled(0)
660666
theta = theta.reshape((-1, 1)) # for broadcasting
661667
xy = (X + Y * 1j) * np.exp(1j * theta) * self.width
662668
xy = xy[:, :, np.newaxis]

lib/matplotlib/tests/test_quiver.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ def test_quiver_with_key():
9595

9696
qk = ax.quiverkey(Q, 0.5, 0.95, 2,
9797
r'$2\, \mathrm{m}\, \mathrm{s}^{-1}$',
98+
angle=-10,
9899
coordinates='figure',
99100
labelpos='W',
100101
fontproperties={'weight': 'bold',
@@ -161,6 +162,20 @@ def test_bad_masked_sizes():
161162
ax.barbs(x, y, u, v)
162163

163164

165+
def test_quiverkey_angles():
166+
# Check that only a single arrow is plotted for a quiverkey when an array
167+
# of angles is given to the original quiver plot
168+
fig, ax = plt.subplots()
169+
170+
X, Y = np.meshgrid(np.arange(2), np.arange(2))
171+
U = V = angles = np.ones_like(X)
172+
173+
q = ax.quiver(X, Y, U, V, angles=angles)
174+
qk = ax.quiverkey(q, 1, 1, 2, 'Label')
175+
# The arrows are only created when the key is drawn
176+
fig.canvas.draw()
177+
assert len(qk.verts) == 1
178+
164179
if __name__ == '__main__':
165180
import nose
166181
nose.runmodule()

0 commit comments

Comments
 (0)