Skip to content

Matplotlib animation

Programming / python / matplotlib

FuncAnimation is Matplotlib’s built-in way to make animations. You give it:

  • a Figure to draw on,
  • an update function that changes existing artists (lines, scatters, images) for each frame,
  • an optional init function to set the starting state,
  • and frames (how many frames or an iterable of frame values).

It repeatedly calls your update function and redraws.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# Data & figure
x = np.linspace(0, 2*np.pi, 400)
fig, ax = plt.subplots()
(line,) = ax.plot([], [], lw=2)   # artist to update
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1.2, 1.2)
ax.grid(True)

def init():
    line.set_data([], [])
    return (line,)       # return a tuple/list of artists

def update(frame):
    # frame is an int (0..N-1) or any object from your frames iterable
    print(f"Frame {frame}")  # for debugging
    y = np.sin(x + 0.05*frame)
    line.set_data(x, y)  # mutate existing artist
    return (line,)

anim = FuncAnimation(
    fig, update, 
    init_func=init,
    frames=200,          # or frames=range(200) or any iterable/generator
    interval=20,         # milliseconds between frames
    blit=True            # only re-draw changed artists (faster on many backends)
)

plt.show()

Note

The callable update must return an iterable of artist when blit=True


Demo: Dynamic graph - Moving x axis

Code
# Source - https://stackoverflow.com/a/17903145
# Posted by tacaswell, modified by community. See post 'Timeline' for change history
# Retrieved 2026-04-13, License - CC BY-SA 3.0

import matplotlib.pylab as plt
import matplotlib.animation as animation
import numpy as np

#create image with format (time,x,y)
image = np.random.rand(100,10,10)

#setup figure
fig = plt.figure()
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)
#set up viewing window (in this case the 25 most recent values)
repeat_length = (np.shape(image)[0]+1)/4
ax2.set_xlim([0,repeat_length])
#ax2.autoscale_view()
ax2.set_ylim([np.amin(image[:,5,5]),np.amax(image[:,5,5])])

#set up list of images for animation


im = ax1.imshow(image[0,:,:])
im2, = ax2.plot([], [], color=(0,0,1))

def func(n):
    im.set_data(image[n,:,:])

    im2.set_xdata(np.arange(n))
    im2.set_ydata(image[0:n, 5, 5])
    if n>repeat_length:
        lim = ax2.set_xlim(n-repeat_length, n)
    else:
        # makes it look ok when the animation loops
        lim = ax2.set_xlim(0, repeat_length)
    return im, im2

ani = animation.FuncAnimation(fig, func, frames=image.shape[0], interval=30, blit=False)

plt.show()