10000 Merge pull request #5458 from DanHickstein/quiver-fixes · matplotlib/matplotlib@174f9d8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 174f9d8

Browse files
committed
Merge pull request #5458 from DanHickstein/quiver-fixes
Removed normalization of arrows in 3D quiver
2 parents 8236ed4 + b81e976 commit 174f9d8

File tree

4 files changed

+38
-10
lines changed

4 files changed

+38
-10
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
New defaults for 3D quiver function in mpl_toolkits.mplot3d.axes3d.py
2+
```````````````````````````
3+
Matplotlib has both a 2D and a 3D ``quiver`` function. These changes affect only the 3D function and make the default behavior of the 3D function match 2D version. There are two changes:
4+
5+
1) The 3D quiver function previously normalized the arrows to be the same length, which makes it unusable for situations where the arrows should be different lengths and does not match the behavior of the 2D function. This normalization behavior is now controlled with the ``normalize`` keyword, which defaults to False.
6+
7+
2) The ``pivot`` keyword now defaults to ``tail`` instead of ``tip``. This was done in order to match the default behavior of the 2D quiver function.
8+
9+
To obtain the previous behavior with the 3D quiver function, one can call the function with ::
10+
11+
ax.quiver(x, y, z, u, v, w, normalize=True, pivot='tip')
12+
13+
where "ax" is a axes3d object created with something like ::
14+
15+
import mpl_toolkits.mplot3d.axes3d
16+
ax = plt.sublot(111, projection='3d')

examples/mplot3d/quiver3d_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
1515
np.sin(np.pi * z))
1616

17-
ax.quiver(x, y, z, u, v, w, length=0.1)
17+
ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True)
1818

1919
plt.show()

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,7 +2477,7 @@ def quiver(self, *args, **kwargs):
24772477
24782478
*X*, *Y*, *Z*:
24792479
The x, y and z coordinates of the arrow locations (default is
2480-
tip of arrow; see *pivot* kwarg)
2480+
tail of arrow; see *pivot* kwarg)
24812481
24822482
*U*, *V*, *W*:
24832483
The x, y and z components of the arrow vectors
@@ -2499,7 +2499,13 @@ def quiver(self, *args, **kwargs):
24992499
25002500
*pivot*: [ 'tail' | 'middle' | 'tip' ]
25012501
The part of the arrow that is at the grid point; the arrow
2502-
rotates about this point, hence the name *pivot*.
2502+
rotates about this point, hence the name *pivot*.
2503+
Default is 'tail'
2504+
2505+
*normalize*: [False | True]
2506+
When True, all of the arrows will be the same length. This
2507+
defaults to False, where the arrows will be different lengths
2508+
depending on the values of u,v,w.
25032509
25042510
Any additional keyword arguments are delegated to
25052511
:class:`~matplotlib.collections.LineCollection`
@@ -2508,6 +2514,7 @@ def quiver(self, *args, **kwargs):
25082514
def calc_arrow(uvw, angle=15):
25092515
"""
25102516
To calculate the arrow head. uvw should be a unit vector.
2517+
We normalize it here:
25112518
"""
25122519
# get unit direction vector perpendicular to (u,v,w)
25132520
norm = np.linalg.norm(uvw[:2])
@@ -2540,7 +2547,9 @@ def calc_arrow(uvw, angle=15):
25402547
# arrow length ratio to the shaft length
25412548
arrow_length_ratio = kwargs.pop('arrow_length_ratio', 0.3)
25422549
# pivot point
2543-
pivot = kwargs.pop('pivot', 'tip')
2550+
pivot = kwargs.pop('pivot', 'tail')
2551+
# normalize
2552+
normalize = kwargs.pop('normalize', False)
25442553

25452554
# handle args
25462555
argi = 6
@@ -2601,7 +2610,10 @@ def calc_arrow(uvw, angle=15):
26012610
# If any row of UVW is all zeros, don't make a quiver for it
26022611
mask = norm > 1e-10
26032612
XYZ = XYZ[mask]
2604-
UVW = UVW[mask] / norm[mask].reshape((-1, 1))
2613+
if normalize:
2614+
UVW = UVW[mask] / norm[mask].reshape((-1, 1))
2615+
else:
2616+
UVW = UVW[mask]
26052617

26062618
if len(XYZ) > 0:
26072619
# compute the shaft lines all at once with an outer product

lib/mpl_toolkits/tests/test_mplot3d.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def test_quiver3d():
215215
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
216216
np.sin(np.pi * z))
217217

218-
ax.quiver(x, y, z, u, v, w, length=0.1)
218+
ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True)
219219

220220
@image_comparison(baseline_images=['quiver3d_empty'], remove_text=True)
221221
def test_quiver3d_empty():
@@ -229,7 +229,7 @@ def test_quiver3d_empty():
229229
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
230230
np.sin(np.pi * z))
231231

232-
ax.quiver(x, y, z, u, v, w, length=0.1)
232+
ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True)
233233

234234
@image_comparison(baseline_images=['quiver3d_masked'], remove_text=True)
235235
def test_quiver3d_masked():
@@ -247,7 +247,7 @@ def test_quiver3d_masked():
247247
u = np.ma.masked_where((-0.4 < x) & (x < 0.1), u, copy=False)
248248
v = np.ma.masked_where((0.1 < y) & (y < 0.7), v, copy=False)
249249

250-
ax.quiver(x, y, z, u, v, w, length=0.1)
250+
ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True)
251251

252252
@image_comparison(baseline_images=['quiver3d_pivot_middle'], remove_text=True,
253253
extensions=['png'])
@@ -262,7 +262,7 @@ def test_quiver3d_pivot_middle():
262262
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
263263
np.sin(np.pi * z))
264264

265-
ax.quiver(x, y, z, u, v, w, length=0.1, pivot='middle')
265+
ax.quiver(x, y, z, u, v, w, length=0.1, pivot='middle', normalize=True)
266266

267267
@image_comparison(baseline_images=['quiver3d_pivot_tail'], remove_text=True,
268268
extensions=['png'])
@@ -277,7 +277,7 @@ def test_quiver3d_pivot_tail():
277277
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
278278
np.sin(np.pi * z))
279279

280-
ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tail')
280+
ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tail', normalize=True)
281281

282282

283283
@image_comparison(baseline_images=['axes3d_labelpad'], extensions=['png'])

0 commit comments

Comments
 (0)
0