Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions lib/matplotlib/animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,19 +878,25 @@ class Animation:
Whether blitting is used to optimize drawing. If the backend does not
support blitting, then this parameter has no effect.

start_paused : bool, default: False
Whether the animation should start in a paused state. If True, the
animation will draw the initial frame but will not begin animating
until `.resume()` is called.

See Also
--------
FuncAnimation, ArtistAnimation
"""

def __init__(self, fig, event_source, blit=False):
def __init__(self, fig, event_source, blit=False, start_paused=False):
self._draw_was_started = False

self._fig = fig
# Disables blitting for backends that don't support it. This
# allows users to request it if available, but still have a
# fallback that works if it is not.
self._blit = blit and fig.canvas.supports_blit
self._start_paused = start_paused

# These are the basics of the animation. The frame sequence represents
# information for each frame of the animation and depends on how the
Expand Down Expand Up @@ -933,8 +939,10 @@ def _start(self, *args):
self._fig.canvas.mpl_disconnect(self._first_draw_id)
# Now do any initial draw
self._init_draw()
# Actually start the event_source.
self.event_source.start()
# Do not start the timer if the animation was requested to start
# in a paused state; the user must call .resume() manually.
if not self._start_paused:
self.event_source.start()

def _stop(self, *args):
# On stop we disconnect all of our events.
Expand Down
48 changes: 48 additions & 0 deletions lib/matplotlib/tests/test_animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,3 +558,51 @@ def test_animation_with_transparency():
# Check that the alpha channel is not 255, so frame has transparency
assert frame.getextrema()[3][0] < 255
plt.close(fig)


def test_animation_start_paused():
"""Test that Animation(start_paused=True) starts in a paused state."""
from unittest.mock import patch

def _make_anim(fig, **kwargs):
line, = fig.axes[0].plot([], [])

def init():
line.set_data([], [])
return line,

def animate(i):
line.set_data([0, 1], [0, i])
return line,

return animation.FuncAnimation(
fig, animate, init_func=init, frames=5, interval=100, **kwargs)

# start_paused=True: event_source.start() should NOT be called in _start
fig1, _ = plt.subplots()
anim1 = _make_anim(fig1, start_paused=True)
with patch.object(anim1.event_source, 'start',
wraps=anim1.event_source.start) as mock_start:
anim1._start()
mock_start.assert_not_called()
plt.close(fig1)

# start_paused=False (default): event_source.start() SHOULD be called
fig2, _ = plt.subplots()
anim2 = _make_anim(fig2)
with patch.object(anim2.event_source, 'start',
wraps=anim2.event_source.start) as mock_start2:
anim2._start()
mock_start2.assert_called_once()
plt.close(fig2)

# start_paused=True then resume(): start() should be called
fig3, _ = plt.subplots()
anim3 = _make_anim(fig3, start_paused=True)
with patch.object(anim3.event_source, 'start',
wraps=anim3.event_source.start) as mock_start3:
anim3._start()
mock_start3.assert_not_called()
anim3.resume()
mock_start3.assert_called_once()
plt.close(fig3)
Loading