Skip to content

Commit e4dadb6

Browse files
committed
Fix getting tuple of animated artists; add comments and test
1 parent da31ed3 commit e4dadb6

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

lib/matplotlib/tests/test_widgets.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,55 @@ def test_span_selector_bound(direction):
916916
assert tool._edge_handles.positions == handle_positions
917917

918918

919+
@pytest.mark.backend('QtAgg', skip_on_importerror=True)
920+
def test_span_selector_animated_artists_callback():
921+
"""Check that the animated artists changed in callbacks are updated."""
922+
x = np.linspace(0, 2 * np.pi, 100)
923+
values = np.sin(x)
924+
925+
fig, ax = plt.subplots()
926+
(ln,) = ax.plot(x, values, animated=True)
927+
(ln2, ) = ax.plot([], animated=True)
928+
929+
plt.pause(0.1)
930+
ax.draw_artist(ln)
931+
fig.canvas.blit(fig.bbox)
932+
933+
def mean(vmin, vmax):
934+
indmin, indmax = np.searchsorted(x, (vmin, vmax))
935+
v = values[indmin:indmax].mean()
936+
print('here', x, v)
937+
ln2.set_data(x, v)
938+
939+
span = widgets.SpanSelector(ax, mean, direction='horizontal',
940+
onmove_callback=mean,
941+
interactive=True,
942+
drag_from_anywhere=True,
943+
useblit=True)
944+
press_data = [1, 2]
945+
move_data = [2, 2]
946+
do_event(span, 'press', xdata=press_data[0], ydata=press_data[1], button=1)
947+
do_event(span, 'onmove', xdata=move_data[0], ydata=move_data[1], button=1)
948+
assert span._get_animated_artists() == (ln, ln2)
949+
assert ln.stale is False
950+
assert ln2.stale
951+
assert ln2.get_ydata() == 0.9547335049088455
952+
span.update()
953+
assert ln2.stale is False
954+
955+
press_data = [4, 2]
956+
move_data = [5, 2]
957+
release_data = [5, 2]
958+
do_event(span, 'press', xdata=press_data[0], ydata=press_data[1], button=1)
959+
do_event(span, 'onmove', xdata=move_data[0], ydata=move_data[1], button=1)
960+
assert ln.stale is False
961+
assert ln2.stale
962+
assert ln2.get_ydata() == -0.9424150707548072
963+
do_event(span, 'release', xdata=release_data[0],
964+
ydata=release_data[1], button=1)
965+
assert ln2.stale is False
966+
967+
919968
def check_lasso_selector(**kwargs):
920969
ax = get_ax()
921970

lib/matplotlib/widgets.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,12 +1840,19 @@ def set_active(self, active):
18401840
self.update_background(None)
18411841

18421842
def _get_animated_artists(self):
1843-
"""Convenience method to get all animated artists of a figure."""
1843+
"""
1844+
Convenience method to get all animated artists of a figure, except
1845+
those already present in self.artists.
1846+
"""
18441847
axes = self.ax.get_figure().get_axes()
18451848
animated_artists = tuple()
18461849
for ax in axes:
1847-
artists = sorted(ax.get_children(), key=lambda x: x.zorder)
1848-
animated_artists += tuple(a for a in artists if a.get_animated())
1850+
# Make sure we don't get the artists already in self.artists
1851+
artists = filter(
1852+
lambda a: a.get_animated() and a not in self.artists,
1853+
ax.get_children()
1854+
)
1855+
animated_artists += tuple(sorted(artists, key=lambda a: a.zorder))
18491856
return animated_artists
18501857

18511858
def update_background(self, event):
@@ -1857,6 +1864,9 @@ def update_background(self, event):
18571864
# Make sure that widget artists don't get accidentally included in the
18581865
# background, by re-rendering the background if needed (and then
18591866
# re-re-rendering the canvas with the visible widget artists).
1867+
# We need to remove all artists which will be drawn when updating
1868+
# the selector: if we have animated artists in the figure, it is safer
1869+
# to redrawn by default, in case they have updated by the callback
18601870
artists = self.artists + self._get_animated_artists()
18611871
needs_redraw = any(artist.get_visible() for artist in artists)
18621872
with ExitStack() as stack:
@@ -1913,9 +1923,10 @@ def update(self):
19131923
self.canvas.restore_region(self.background)
19141924
else:
19151925
self.update_background(None)
1926+
# We need to draw all artists, which are not included in the
1927+
# background, therefore we add self._get_animated_artists()
19161928
for artist in self.artists + self._get_animated_artists():
1917-
if artist.stale:
1918-
self.ax.draw_artist(artist)
1929+
self.ax.draw_artist(artist)
19191930
self.canvas.blit(self.ax.bbox)
19201931
else:
19211932
self.canvas.draw_idle()

0 commit comments

Comments
 (0)