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

Skip to content

Commit 0539da4

Browse files
committed
Make animation blit cache robust against 3d viewpoint changes.
Instead of connecting to the xlim_changed/ylim_changed events to clear the blit cache, use Axes._get_view(), which also works for 3d axes.
1 parent 491e8ac commit 0539da4

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

lib/matplotlib/animation.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,7 @@ def _pre_draw(self, framedata, blit):
11841184
# Perform any cleaning or whatnot before the drawing of the frame.
11851185
# This default implementation allows blit to clear the frame.
11861186
if blit:
1187-
self._blit_clear(self._drawn_artists, self._blit_cache)
1187+
self._blit_clear(self._drawn_artists)
11881188

11891189
def _draw_frame(self, framedata):
11901190
# Performs actual drawing of the frame.
@@ -1196,53 +1196,53 @@ def _post_draw(self, framedata, blit):
11961196
# the draw, which can be a direct draw_idle() or make use of the
11971197
# blitting.
11981198
if blit and self._drawn_artists:
1199-
self._blit_draw(self._drawn_artists, self._blit_cache)
1199+
self._blit_draw(self._drawn_artists)
12001200
else:
12011201
self._fig.canvas.draw_idle()
12021202

12031203
# The rest of the code in this class is to facilitate easy blitting
1204-
def _blit_draw(self, artists, bg_cache):
1204+
def _blit_draw(self, artists):
12051205
# Handles blitted drawing, which renders only the artists given instead
12061206
# of the entire figure.
1207-
updated_ax = []
1208-
1207+
updated_ax = {a.axes for a in artists}
12091208
# Enumerate artists to cache axes' backgrounds. We do not draw
12101209
# artists yet to not cache foreground from plots with shared axes
1211-
for a in artists:
1212-
# If we haven't cached the background for this axes object, do
1213-
# so now. This might not always be reliable, but it's an attempt
1214-
# to automate the process.
1215-
if a.axes not in bg_cache:
1216-
bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox)
1217-
1218-
# Make a separate pass to draw foreground
1210+
for ax in updated_ax:
1211+
# If we haven't cached the background for the current view of this
1212+
# axes object, do so now. This might not always be reliable, but
1213+
# it's an attempt to automate the process.
1214+
cur_view = ax._get_view()
1215+
view, bg = self._blit_cache.get(ax, (object(), None))
1216+
if cur_view != view:
1217+
self._blit_cache[ax] = (
1218+
cur_view, ax.figure.canvas.copy_from_bbox(ax.bbox))
1219+
# Make a separate pass to draw foreground.
12191220
for a in artists:
12201221
a.axes.draw_artist(a)
1221-
updated_ax.append(a.axes)
1222-
12231222
# After rendering all the needed artists, blit each axes individually.
1224-
for ax in set(updated_ax):
1223+
for ax in updated_ax:
12251224
ax.figure.canvas.blit(ax.bbox)
12261225

1227-
def _blit_clear(self, artists, bg_cache):
1226+
def _blit_clear(self, artists):
12281227
# Get a list of the axes that need clearing from the artists that
12291228
# have been drawn. Grab the appropriate saved background from the
12301229
# cache and restore.
12311230
axes = {a.axes for a in artists}
1232-
for a in axes:
1233-
if a in bg_cache:
1234-
a.figure.canvas.restore_region(bg_cache[a])
1231+
for ax in axes:
1232+
try:
1233+
view, bg = self._blit_cache[ax]
1234+
except KeyError:
1235+
continue
1236+
if ax._get_view() == view:
1237+
ax.figure.canvas.restore_region(bg)
1238+
else:
1239+
self._blit_cache.pop(ax)
12351240

12361241
def _setup_blit(self):
12371242
# Setting up the blit requires: a cache of the background for the
12381243
# axes
12391244
self._blit_cache = dict()
12401245
self._drawn_artists = []
1241-
for ax in self._fig.axes:
1242-
ax.callbacks.connect('xlim_changed',
1243-
lambda ax: self._blit_cache.pop(ax, None))
1244-
ax.callbacks.connect('ylim_changed',
1245-
lambda ax: self._blit_cache.pop(ax, None))
12461246
self._resize_id = self._fig.canvas.mpl_connect('resize_event',
12471247
self._handle_resize)
12481248
self._post_draw(None, self._blit)
@@ -1523,7 +1523,7 @@ def _pre_draw(self, framedata, blit):
15231523
"""Clears artists from the last frame."""
15241524
if blit:
15251525
# Let blit handle clearing
1526-
self._blit_clear(self._drawn_artists, self._blit_cache)
1526+
self._blit_clear(self._drawn_artists)
15271527
else:
15281528
# Otherwise, make all the artists from the previous frame invisible
15291529
for artist in self._drawn_artists:

0 commit comments

Comments
 (0)