8000 Enforce that Line data modifications are sequences · matplotlib/matplotlib@45e6f9a · GitHub
[go: up one dir, main page]

Skip to content

Commit 45e6f9a

Browse files
QuLogictacaswell
authored andcommitted
Enforce that Line data modifications are sequences
When creating a Line2D, x/y data is required to be a sequence. This is not enforced when modifying the data, or with Line3D.
1 parent eb92923 commit 45e6f9a

File tree

7 files changed

+46
-9
lines changed

7 files changed

+46
-9
lines changed

lib/matplotlib/lines.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,8 @@ def set_xdata(self, x):
12761276
----------
12771277
x : 1D array
12781278
"""
1279+
if not np.iterable(x):
1280+
raise RuntimeError('x must be a sequence')
12791281
self._xorig = copy.copy(x)
12801282
self._invalidx = True
12811283
self.stale = True
@@ -1288,6 +1290,8 @@ def set_ydata(self, y):
12881290
----------
12891291
y : 1D array
12901292
"""
1293+
if not np.iterable(y):
1294+
raise RuntimeError('y must be a sequence')
12911295
self._yorig = copy.copy(y)
12921296
self._invalidy = True
12931297
self.stale = True

lib/matplotlib/tests/test_lines.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,19 @@ def test_set_line_coll_dash():
8383
ax.contour(np.random.randn(20, 30), linestyles=[(0, (3, 3))])
8484

8585

86+
def test_invalid_line_data():
87+
with pytest.raises(RuntimeError, match='xdata must be'):
88+
mlines.Line2D(0, [])
89+
with pytest.raises(RuntimeError, match='ydata must be'):
90+
mlines.Line2D([], 1)
91+
92+
line = mlines.Line2D([], [])
93+
with pytest.raises(RuntimeError, match='x must be'):
94+
line.set_xdata(0)
95+
with pytest.raises(RuntimeError, match='y must be'):
96+
line.set_ydata(0)
97+
98+
8699
@image_comparison(['line_dashes'], remove_text=True)
87100
def test_line_dashes():
88101
fig, ax = plt.subplots()

lib/matplotlib/tests/test_widgets.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ def mean(vmin, vmax):
869869
# Return mean of values in x between *vmin* and *vmax*
870870
indmin, indmax = np.searchsorted(x, (vmin, vmax))
871871
v = values[indmin:indmax].mean()
872-
ln2.set_data(x, v)
872+
ln2.set_data(x, np.full_like(x, v))
873873

874874
span = widgets.SpanSelector(ax, mean, direction='horizontal',
875875
onmove_callback=mean,
@@ -886,7 +886,7 @@ def mean(vmin, vmax):
886886
assert span._get_animated_artists() == (ln, ln2)
887887
assert ln.stale is False
888888
assert ln2.stale
889-
assert ln2.get_ydata() == 0.9547335049088455
889+
assert_allclose(ln2.get_ydata(), 0.9547335049088455)
890890
span.update()
891891
assert ln2.stale is False
892892

@@ -899,7 +899,7 @@ def mean(vmin, vmax):
899899
do_event(span, 'onmove', xdata=move_data[0], ydata=move_data[1], button=1)
900900
assert ln.stale is False
901901
assert ln2.stale
902-
assert ln2.get_ydata() == -0.9424150707548072
902+
assert_allclose(ln2.get_ydata(), -0.9424150707548072)
903903
do_event(span, 'release', xdata=release_data[0],
904904
ydata=release_data[1], button=1)
905905
assert ln2.stale is False

lib/matplotlib/widgets.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3347,7 +3347,8 @@ def extents(self, extents):
33473347
# Update displayed handles
33483348
self._corner_handles.set_data(*self.corners)
33493349
self._edge_handles.set_data(*self.edge_centers)
3350-
self._center_handle.set_data(*self.center)
3350+
x, y = self.center
3351+
self._center_handle.set_data([x], [y])
33513352
self.set_visible(self._visible)
33523353
self.update()
33533354

lib/mpl_toolkits/mplot3d/art3d.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ def __init__(self, xs, ys, zs, *args, **kwargs):
200200
Additional arguments are passed onto :func:`~matplotlib.lines.Line2D`.
201201
"""
202202
super().__init__([], [], *args, **kwargs)
203-
self._verts3d = xs, ys, zs
203+
self.set_data_3d(xs, ys, zs)
204204

205205
def set_3d_properties(self, zs=0, zdir='z'):
206206
"""
@@ -240,9 +240,11 @@ def set_data_3d(self, *args):
240240
Accepts x, y, z arguments or a single array-like (x, y, z)
241241
"""
242242
if len(args) == 1:
243-
self._verts3d = args[0]
244-
else:
245-
self._verts3d = args
243+
args = args[0]
244+
for name, xyz in zip('xyz', args):
245+
if not np.iterable(xyz):
246+
raise RuntimeError(f'{name} must be a sequence')
247+
self._verts3d = args
246248
self.stale = True
247249

248250
def get_data_3d(self):

lib/mpl_toolkits/mplot3d/axis3d.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def _tick_update_position(tick, tickxs, tickys, labelpos):
4747
tick.tick1line.set_linestyle('-')
4848
tick.tick1line.set_marker('')
4949
tick.tick1line.set_data(tickxs, tickys)
50-
tick.gridline.set_data(0, 0)
50+
tick.gridline.set_data([0], [0])
5151

5252

5353
class Axis(maxis.XAxis):

lib/mpl_toolkits/mplot3d/tests/test_axes3d.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,23 @@ def test_plot_scalar(fig_test, fig_ref):
310310
ax2.plot(1, 1, "o")
311311

312312

313+
def test_invalid_line_data():
314+
with pytest.raises(RuntimeError, match='x must be'):
315+
art3d.Line3D(0, [], [])
316+
with pytest.raises(RuntimeError, match='y must be'):
317+
art3d.Line3D([], 0, [])
318+
with pytest.raises(RuntimeError, match='z must be'):
319+
art3d.Line3D([], [], 0)
320+
321+
line = art3d.Line3D([], [], [])
322+
with pytest.raises(RuntimeError, match='x must be'):
323+
line.set_data_3d(0, [], [])
324+
with pytest.raises(RuntimeError, match='y must be'):
325+
line.set_data_3d([], 0, [])
326+
with pytest.raises(RuntimeError, match='z must be'):
327+
line.set_data_3d([], [], 0)
328+
329+
313330
@mpl3d_image_comparison(['mixedsubplot.png'])
314331
def test_mixedsubplots():
315332
def f(t):

0 commit comments

Comments
 (0)
0