Skip to content

FuncAnimation: interactive zoom/pan with blitting does not work #13478

Closed
@onatt

Description

@onatt

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
a
After pan: The sinusoidal line is not shifted correctly
b

Expected outcome
c

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)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions