8000 Make animation blit cache robust against 3d viewpoint changes. · matplotlib/matplotlib@e0c6597 · GitHub
[go: up one dir, main page]

Skip to content

Commit e0c6597

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 981b82e commit e0c6597

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

lib/matplotlib/animation.py

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,7 @@ def _pre_draw(self, framedata, blit):
11741174
# Perform any cleaning or whatnot before the drawing of the frame.
11751175
# This default implementation allows blit to clear the frame.
11761176
if blit:
1177-
self._blit_clear(self._drawn_artists, self._blit_cache)
1177+
self._blit_clear(self._drawn_artists)
11781178

11791179
def _draw_frame(self, framedata):
11801180
# Performs actual drawing of the frame.
@@ -1186,53 +1186,52 @@ def _post_draw(self, framedata, blit):
11861186
# the draw, which can be a direct draw_idle() or make use of the
11871187
# blitting.
11881188
if blit and self._drawn_artists:
1189-
self._blit_draw(self._drawn_artists, self._blit_cache)
1189+
self._blit_draw(self._drawn_artists)
11901190
else:
11911191
self._fig.canvas.draw_idle()
11921192

11931193
# The rest of the code in this class is to facilitate easy blitting
1194-
def _blit_draw(self, artists, bg_cache):
1194+
def _blit_draw(self, artists):
11951195
# Handles blitted drawing, which renders only the artists given instead
11961196
# of the entire figure.
1197-
updated_ax = []
1198-
1197+
updated_ax = {a.axes for a in artists}
11991198
# Enumerate artists to cache axes' backgrounds. We do not draw
12001199
# artists yet to not cache foreground from plots with shared axes
1201-
for a in artists:
1202-
# If we haven't cached the background for this axes object, do
1203-
# so now. This might not always be reliable, but it's an attempt
1204-
# to automate the process.
1205-
if a.axes not in bg_cache:
1206-
bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox)
1207-
1208-
# Make a separate pass to draw foreground
1200+
for ax in updated_ax:
1201+
# If we haven't cached the background for the current view of this
1202+
# axes object, do so now. This might not always be reliable, but
1203+
# it's an attempt to automate the process.
1204+
cur_view = ax._get_view()
1205+
view, bg = self._blit_cache.get(ax, (object(), None))
1206+
if cur_view != view:
1207+
self._blit_cache[ax] = (
1208+
cur_view, ax.figure.canvas.copy_from_bbox(ax.bbox))
1209+
# Make a separate pass to draw foreground.
12091210
for a in artists:
12101211
a.axes.draw_artist(a)
1211-
updated_ax.append(a.axes)
1212-
12131212
# After rendering all the needed artists, blit each axes individually.
1214-
for ax in set(updated_ax):
1213+
for ax in updated_ax:
12151214
ax.figure.canvas.blit(ax.bbox)
12161215

1217-
def _blit_clear(self, artists, bg_cache):
1216+
def _blit_clear(self, artists):
12181217
# Get a list of the axes that need clearing from the artists that
12191218
# have been drawn. Grab the appropriate saved background from the
12201219
# cache and restore.
12211220
axes = {a.axes for a in artists}
1222-
for a in axes:
1223-
if a in bg_cache:
1224-
a.figure.canvas.restore_region(bg_cache[a])
1221+
for ax in axes:
1222+
try:
1223+
view, bg = self._blit_cache[ax]
1224+
except KeyError:
1225+
pass
1226+
else:
1227+
if ax._get_view() == view:
1228+
ax.figure.canvas.restore_region(bg)
12251229

12261230
def _setup_blit(self):
12271231
# Setting up the blit requires: a cache of the background for the
12281232
# axes
12291233
self._blit_cache = dict()
12301234
self._drawn_artists = []
1231-
for ax in self._fig.axes:
1232-
ax.callbacks.connect('xlim_changed',
1233-
lambda ax: self._blit_cache.pop(ax, None))
1234-
ax.callbacks.connect('ylim_changed',
1235-
lambda ax: self._blit_cache.pop(ax, None))
12361235
self._resize_id = self._fig.canvas.mpl_connect('resize_event',
12371236
self._handle_resize)
12381237
self._post_draw(None, self._blit)
@@ -1515,7 +1514,7 @@ def _pre_draw(self, framedata, blit):
15151514
'''
15161515
if blit:
15171516
# Let blit handle clearing
1518-
self._blit_clear(self._drawn_artists, self._blit_cache)
1517+
self._blit_clear(self._drawn_artists)
15191518
else:
15201519
# Otherwise, make all the artists from the previous frame invisible
15211520
for artist in self._drawn_artists:

0 commit comments

Comments
 (0)
0