Closed
Description
Bug report
Bug summary
In an animation using blitting that contains some static graphics elements, the static parts of the figure are not updated after an interactive zoom/pan event. However, they are correctly updated after an resize event.
Code for reproduction
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.animation
t = np.linspace(0, 10, 100)
y = np.sin(t)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(t, y)
point, = ax.plot(0, 0, 'o')
def update(i):
point.set_data([t[i], y[i]])
return point,
ani = mpl.animation.FuncAnimation(fig, update, frames=t.size, blit=True)
plt.tight_layout()
plt.show()
Actual outcome
After an interactive zoom/pan operation the axes is redrawn, but the line plot stays on it's original position on screen. It seems that for some reason, a zoom/pan does not trigger a new initialization of the blitting.
Before pan: Point moves along the sinusoidal line
After pan: The sinusoidal line is not shifted correctly
Matplotlib version
- Operating system: Linux 4.20.10 (same problem with Windows 10)
- Matplotlib version: 3.0.2
- Matplotlib backend (
print(matplotlib.get_backend())
): Qt5Agg (TkAgg shows the same problem) - Python version: 3.0.2
- Jupyter version (if applicable): n/a
Proposed fix
The following modification of matplotlib/animation.py fixes the problem:
class Animation(object):
...
def _setup_blit(self):
# Setting up the blit requires: a cache of the background for the
# axes
self._blit_cache = dict()
self._drawn_artists = []
def remove_from_cache(ax):
try:
del self._blit_cache[ax]
except KeyError:
pass
for ax in self._fig.axes:
ax.callbacks.connect('xlim_changed', remove_from_cache)
ax.callbacks.connect('ylim_changed', remove_from_cache)
self._resize_id = self._fig.canvas.mpl_connect('resize_event', self._handle_resize)
self._post_draw(None, self._blit)