Skip to content

Commit 762403f

Browse files
committed
Connect the Animation event source callback in the constructor.
Currently, there is no "official" way of knowing whether a Figure hosts an Animation. Yet, this information can be of interest e.g. for third-party backends. For example, a variant of the ipython inline backend could choose to actually animate its (inline) output in that case; indeed, this feature was already supported by the itermplot backend. itermplot is actually now outdated but the general idea can still be made to work -- I have a working patch for mplterm. The idea is for the backend to override FigureCanvas.new_timer (on the backend-specific canvas subclass) to internally register any timer that gets created (e.g. by the animation module), then, when the canvas is show()n, to first trigger a fake draw_event so that animation callbacks (if any) get attached to the timer, and then to introspect what callbacks have been attached to the timer and retrieve any Animation instance from that. While this all works, there is brittleness on a specific point, namely the need to trigger the fake draw_event (as the callback only gets attached in Animation._start) early in show(): at that point there may be no renderer available so one cannot construct a real DrawEvent (in fact, itermplot just sets renderer to None). If there are additional (end-user-provided) draw_event handlers connected, they may well error out on this fake draw_event. Yet, it is easy to work around this problem, by connecting the animation stepping callback immediately to the timer when the Animation is constructed, rather than waiting for the first draw. The timer is still only *started* at the first draw, so nothing changes from the point of view of the end user. Note that this does not create a strong reference holding the Animation in the "usual" case (of backends that don't keep a reference to the timers they create) -- it's just a reference loop of the Animation holding the Timer holding an Animation method as a callback.
1 parent 0b7a88a commit 762403f

File tree

1 file changed

+2
-5
lines changed

1 file changed

+2
-5
lines changed

lib/matplotlib/animation.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,7 @@ def __init__(self, fig, event_source=None, blit=False):
891891
# that cause the frame sequence to be iterated.
892892
self.frame_seq = self.new_frame_seq()
893893
self.event_source = event_source
894+
self.event_source.add_callback(self._step)
894895

895896
# Instead of starting the event source now, we connect to the figure's
896897
# draw_event, so that we only start once the figure has been drawn.
@@ -923,13 +924,9 @@ def _start(self, *args):
923924
return
924925
# First disconnect our draw event handler
925926
self._fig.canvas.mpl_disconnect(self._first_draw_id)
926-
927927
# Now do any initial draw
928928
self._init_draw()
929-
930-
# Add our callback for stepping the animation and
931-
# actually start the event_source.
932-
self.event_source.add_callback(self._step)
929+
# Actually start the event_source.
933930
self.event_source.start()
934931

935932
def _stop(self, *args):

0 commit comments

Comments
 (0)