Show don’t Tell with Matplotlib Animations and ImageIO
I’ve often found that the best way to convey information is through animations, not static images. In particular, knowing how to make a GIF in Matplotlib and Pyplot opens up many opportunities for efficient knowledge sharing. This article is a tutorial for Matplotlib Animations and making GIFs in Pyplot.
We’re going to work on a case study which was the content of a previous article about the physics of golf. In that article we used Pyplot GIFs to show how physics can inform golf putting strategy. The combination of dynamic Matplotlib animations alongside static figures allowed me to most easily tell the story I wanted to tell.
As this is a coding tutorial, all of our code is available on The Data Jocks github. The specific code exists in the Golf Physics repo which contains two modules with useful functions for making visualizations related to golf physics.
Why Use Matplotlib for Animations?
Most people who know one coding language know how to use multiple languages. This can make it difficult to decide which language to use for specific applications. For making GIFs and animations, I find Matplotlib to be the easiest.
For a quick intro on how to install Matplotlib, see the helpful video below!
Matplotlib is designed to mimic as closely as possible the commercial Matlab language. While Matlab is often scoffed at by true software engineers, it is more highly regarded among scientists and physical engineers. The reason for this is that Matlab makes beautiful plots and visualizations.
Because Matplotlib is designed to closely mimic Matlab, Matplotlib inherits Matlab’s penchant for beautiful visualization. This is the main reason I like to use Matplotlib for animations and GIFs.
Matplotlib also has a huge advantage over Matlab because its base language is Python. No language is, as of 2023, better supported and used more than Python. The combination of beautiful visualizations and ease of use makes Matplotlib and Pyplot for GIFs the perfect tool to use.
Matplotlib for Animations, Quickly
The process of creating GIFs in Matplotlib can be broken down into three steps, only two of which actually involve coding. These Matplotlib animation steps are:
- Decide the story you want to tell
- Use Matplotlib to create still images
- Use the ImageIO package to stitch the images together into a single GIF
Step 1: Decide on a Story to Tell
The first step is to decide a story to tell with your Matplotlib animation and make sure that an animation is the right way to get the point across. Adding motion into your visualizations can either be powerful or distracting.
Make sure that the motion and the evolution of your graphics over time actually adds to the experience. If the motion is distracting, you were probably better off using a still image in the first place.
Step 2: Use Matplotlib and Pyplot to Create Still Images
In order to make a GIF in Matplotlib, you need to create each of the still images individually. The magic comes from stitching together a sequence of slowly changing still images to show progression over time. The code below shows the basic functionality for creating a still image with labels in Matplotlib and Pyplot.
There are many, many variations on this basic functionality. However, this is as simple as it gets. First, you plot the data on a pair of axes using the plot method from Pyplot. Then, you can change the limits of your axes using the xlim and ylim methods. Finally, you can add labels and titles as shown in the last three lines of the above picture.
The last step we should do is, for each still frame in our Matplotlib animation, we want to save the image to the disk using the Pyplot savefig method. Then, the figure should be closed so that we start with a blank slate when making the next image in our Matplotlib GIF.
Taken together, these few lines of code can create a still image. The next step is to save the images and stitch them together to make the gif.
Combining Images into a GIF with ImageIO
To make the still images into a GIF, we need to
- Load each image
- Append it to the end of the GIF
- Delete the static image from the disk
The following code shows how that might be done.
First, we need to create a writer object which is used to write objects to the disk. We use it to write GIFs. The first argument is the name of the file to be created. Notice the “.gif” file type. Second, the mode “I” (capital) lets us know we will be writing multiple images.
After this, the process is simple. First we read a saved image from the disk. Then, we use the writer object to add this image to the GIF. Finally, to avoid disk clutter, we remove all the saved still frames from the disk. This last step is optional yet highly recommended.
That is truly it. This process is enough to create the frames from scratch and combine them into a GIF using Matplotlib and ImageIO. The next section shows how we used some more advanced plotting options to do this in a study about golf physics.
Matplotlib Gif Tutorial: Case Study
We recently used this process to create GIFs when talking about the physics of golf. We’re going to use that as a case study for making GIFs. We’ll go through each of the three steps we prveiously identified and show how they worked in our case study.
Step 1: Decide on a Story to Tell
The point of our article was to discuss the differences between putting uphill and downhill. The key difference is whether gravity assists in decelerating the golf ball or not. The net effect was that when putting uphill, a putt slows down more quickly.
I decided this was a natural opportunity to apply GIFs. This decision was made because putting has a natural time evolution. The ball starts out moving quickly and slows down before coming to rest. Because the temporal evolution of the physics was an important consideration, a GIF in matplotlib aids in the analysis and is not distracting.
The GIF we want to make is to show the putt from start to finish complete with the observation of the ball slowing down as it rolls. To start, we need to make still frames to do this.
Step 2: Use Matplotlib and Pyplot to Create Still Images
My goal was to use Pyplot to create GIFs of golf balls rolling either up or downhill. The first step was understanding the physics and writing scripts to compute the ball’s position after a certain amount of time had passed. This was fairly straightforward.
What was more complicated was drawing the green and the ball. An example frame looks like this:
Though it looks very simple, this plot actually has 6 different things going on.
- The slope was plotted using the normal plot method from Pyplot, a uniformly spaced grid of x values, and y-value at the correct slope
- The ball was created using the Matplotlib patches module and drawing circles at given locations.
- The flagpole was using with the “patches” rectangle feature
- The flag itself was created using the “patches” polygon feature
- The sky was created by plotting “above the slope” blue and setting it to a transparent value to make it lighter. This was done using the Pyplot fill_between method.
- The ground was created by plotting “below the slope” green. This also used fill_between.
All in all, these features combined to make the putting green. The last steps were just to set the x and y-axis view limits and, more importantly, to remove the tick marks and axis labels. Removing the tick mark and axis labels makes this look more like a picture and less like a scientific plot.
The image below shows each of these steps which are wrapped inside a function definition to provide the scenario parameters for hole location, ball location, incline, etc.
After this, we need to create the GIF
Combining Images into a GIF with ImageIO
For us, creating the GIF is no more complicated than shown in the generic example above. However, there is a bit of logic to decide what type of image to show. There are four possibilities:
- The ball hasn’t reached the hole yet and stopped moving. Here, the putt has been missed
- The ball hasn’t reached the hole yet but is still in motion. Here, the outcome is uncertain.
- The ball reached the hole and went in.
- The ball reached the hole but was moving too fast and skipped over the hole.
We wrote more physics-based scripts to determine which of these things is the case at each instant. Then, we drew the appropriate still-frame for where the ball was. The end result was a GIF like one of the two below.
This GIF cleanly shows the velocity of the putt slowing over time. And, when compared to a downhill putt, it is clear that the slope has a dramatic effect on how a putt works.
By using Matplotlib animations, we were able to make our point in a clear, concise manner. If a picture is worth 1000 words, how many is a video worth?
To receive email updates when new articles are posted, use the subscription form below!