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

Skip to content

Commit e9677c1

Browse files
efiringImportanceOfBeingErnest
authored andcommitted
ENH: Add argument size validation to quiver. (#14424)
Closes #14060.
1 parent 9856ec2 commit e9677c1

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

lib/matplotlib/quiver.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,16 @@
7272
U, V : 1D or 2D array-like
7373
The x and y direction components of the arrow vectors.
7474
75+
They must have the same number of elements, matching the number of arrow
76+
locations. They may be masked.
77+
7578
C : 1D or 2D array-like, optional
7679
Numeric data that defines the arrow colors by colormapping via *norm* and
7780
*cmap*.
7881
7982
This does not support explicit colors. If you want to set colors directly,
80-
use *color* instead.
83+
use *color* instead. The size of *C* must match the number of arrow
84+
locations.
8185
8286
units : {'width', 'height', 'dots', 'inches', 'x', 'y' 'xy'}, default: 'width'
8387
The arrow dimensions (except for *length*) are measured in multiples of
@@ -428,10 +432,13 @@ def _parse_args(*args, caller_name='function'):
428432
Y = Y.ravel()
429433
if len(X) == nc and len(Y) == nr:
430434
X, Y = [a.ravel() for a in np.meshgrid(X, Y)]
435+
elif len(X) != len(Y):
436+
raise ValueError('X and Y must be the same size, but '
437+
f'X.size is {X.size} and Y.size is {Y.size}.')
431438
else:
432439
indexgrid = np.meshgrid(np.arange(nc), np.arange(nr))
433440
X, Y = [np.ravel(a) for a in indexgrid]
434-
441+
# Size validation for U, V, C is left to the set_UVC method.
435442
return X, Y, U, V, C
436443

437444

@@ -589,9 +596,16 @@ def set_UVC(self, U, V, C=None):
589596
# to an array that might change before draw().
590597
U = ma.masked_invalid(U, copy=True).ravel()
591598
V = ma.masked_invalid(V, copy=True).ravel()
592-
mask = ma.mask_or(U.mask, V.mask, copy=False, shrink=True)
593599
if C is not None:
594600
C = ma.masked_invalid(C, copy=True).ravel()
601+
for name, var in zip(('U', 'V', 'C'), (U, V, C)):
602+
if var is not None and var.size != self.N:
603+
raise ValueError(f'Argument {name} has a size {var.size}'
604+
f' which does not match {self.N},'
605+
' the number of arrow positions')
606+
607+
mask = ma.mask_or(U.mask, V.mask, copy=False, shrink=True)
608+
if C is not None:
595609
mask = ma.mask_or(mask, C.mask, copy=False, shrink=True)
596610
if mask is ma.nomask:
597611
C = C.filled()

lib/matplotlib/tests/test_quiver.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,27 @@ def test_quiver_number_of_args():
5151
plt.quiver(X, X, X, X, X, X)
5252

5353

54+
def test_quiver_arg_sizes():
55+
X2 = [1, 2]
56+
X3 = [1, 2, 3]
57+
with pytest.raises(ValueError,
58+
match=('X and Y must be the same size, but '
59+
'X.size is 2 and Y.size is 3.')):
60+
plt.quiver(X2, X3, X2, X2)
61+
with pytest.raises(ValueError,
62+
match=('Argument U has a size 3 which does not match 2,'
63+
' the number of arrow positions')):
64+
plt.quiver(X2, X2, X3, X2)
65+
with pytest.raises(ValueError,
66+
match=('Argument V has a size 3 which does not match 2,'
67+
' the number of arrow positions')):
68+
plt.quiver(X2, X2, X2, X3)
69+
with pytest.raises(ValueError,
70+
match=('Argument C has a size 3 which does not match 2,'
71+
' the number of arrow positions')):
72+
plt.quiver(X2, X2, X2, X2, X3)
73+
74+
5475
def test_no_warnings():
5576
fig, ax = plt.subplots()
5677

0 commit comments

Comments
 (0)