Last Updated on July 14, 2022 by Jay
Matplotlib is a powerful Python charting library, but many people probably don’t know it can create animation plots.
What Is an Animation?
Simply put, an animation consists of a series of static images with slight variations. When we put these static images together and quickly flip through them, our eyes and brain kind of cheat us and make it appear the images are moving (although they are not).
Based on this understanding, to make an animated plot, we need to:
- Create lots of static images/charts
- Put them in order and flip through
We can use pip to install matplotlib, simply type the following in a command prompt/terminal window:
pip install matplotlib
Animation with Matplotlib
We are going to make a simple animation with matplotlib – a red dot that moves in a circle with a radius = 1.5.
First, we need a function to calculate the x and y coordinates of a circle. Instead of using the x^2 + y^2 = r^2 formula, I’m using the parametric representation of a circle:
- x = r*cos(t)
- y = r*sin(t)
- where t is an angle measure
If you want to know the details about this equation, feel free to search for that on Wikipedia. I won’t get into that here.
%matplotlib notebook import matplotlib.pyplot as plt import math from matplotlib.animation import FuncAnimation def circle_coords(r, step): ''' A function that calculates x, y coordinates of a circle with radius=r Arguments: r - radius step - the t value, smaller value means more steps are needed to complete a full circle bigger value means less steps are needed to complete a full circle Returns: a list of tuples [(x,y)] coordiates for a circle ''' coords =  t = 0 while t < 2* math.pi: coords.append((r*math.cos(t), r*math.sin(t))) t += step return coords coords = circle_coords(1.5, 0.1) coords[:5] [(1.5, 0.0), (1.4925062479170388, 0.14975012497024223), (1.4700998667618626, 0.2980039961925918), (1.433004733688409, 0.4432803099920094), (1.3815914910043277, 0.5841275134629758)]
Feel free to run the above code and take a look at what’s inside coords.
Step 1 – Create One Static Chart
Let’s create a chart with a red dot for the first set of (x,y) coordinates in the coords.
fig, ax = plt.subplots() ax.scatter(x=coords,y=coords, c='red', marker = 'o')
This code creates a red dot at exactly (1.5, 0):
Step 2 – Create Many Static Charts
The next step is to create lots of static charts with slight variations. We’ll create 5 charts using the first 5 coordinates to illustrate this:
fig, axs = plt.subplots(nrows = 1, ncols = 5, figsize = (10, 5), tight_layout = True) for i, ax in enumerate(axs): ax.scatter(x=coords[i],y=coords[i], c='red', marker = 'o') ax.set_xlim([0,2]) ax.set_ylim([-0.5,2])
Please bear with me on the narrow charts. I hope you can see that the dot is kind of “moving” towards up and right as we skim through each chart.
FuncAnimation Module in Matplotlib
Technically, we just need to create many static charts (one for each of the coordinates), then combine them together and we’ll have an animation. However, the matplotlib library offers a FuncAnimation module to do that.
To use the FuncAnimation, we need a function to draw the static charts. The name of the drawing function doesn’t matter, we’ll name it update():
- The drawing function takes 1 argument i, which is meant to be the frame number.
- The function will clear our chart at the beginning of each call, so we’ll see only 1 red dot at each frame.
- ax.set_xlim() and ax.set_ylim() functions to make sure we fix the x and y axis
- ax.scatter() draws exactly one red dot at a time.
from matplotlib.animation import FuncAnimation def update(i): ax.clear() ax.set_facecolor(plt.cm.Blues(.2)) ax.set_xlim([-2,2]) ax.set_ylim([-2,2]) ax.set_title('circling') ax.scatter(x=coords[i],y=coords[i], c='red', marker='o') [spine.set_visible(False) for spine in ax.spines.values()] #remove chart outlines
Now we have the drawing function, we can create the FuncAnimation object, which takes the following arguments:
- fig – the figure object to draw on
- func – the drawing / update function
- frames – the number of frames (static images) to create
- interval – delay between frames in milliseconds
We can even save this awesome animation as an animated gif and send it to others!
fig, ax = plt.subplots(figsize=(6,6)) anime = FuncAnimation( fig = fig, func = update, frames = len(coords), interval = 50 ) anime.save('circle.gif')