Spice Up Your Python Visualizations with Matplotlib Animations | by Tony Yiu | Towards Data Science

If you are interested in my code, you can find it here on my GitHub. The code throws an error (that I could not get rid of for the life of me) the first time you run it. But if you just execute the same cell again, it will run fine.
This post is not an obviously data science post but it does have data science and business intelligence applications. Python’s Matplotlib is the go to library for plotting and visualizing data. We are all familiar with line plots, bar plots, and heat maps. But did you know you can also make simple animations using Matplotlib?
Below is an example of an animation created in Matplotlib. It shows John Conway’s The Game of Life — a coding challenge from Metis that gave me an excuse to create my first Python animation. Check out the gif of the finished result:
If you are interested in how I coded up The Game of Life, please refer to my code (and comments) on my GitHub. This blog will primarily focus on how to add animations in python using Matplotlib.
But for those of you that are unfamiliar with the simulation (it’s more a simulation that you watch rather than a game that you play), here are the rules:
We start with a N by N sized board (50 by 50 in my animations).
We populate a random number of cells on our board with organisms (I started the simulation by randomly filling 1,500 of the 2,500 cells on the board with an organism).
Each occupied cell with one or fewer neighbors dies.
Each occupied cell with four or more neighbors dies.
Each occupied cell with two or three neighbors survives.
Each empty cell with exactly three neighbors develops a new organism.
We start by importing the libraries we need.
import timefrom IPython import displayimport matplotlib.pyplot as pltimport matplotlib.animation as animation
We will take advantage of the FuncAnimation() function from matplotlib’s animation module. FuncAnimation() animates an image by calling a function repeatedly, updating the image on each call. We will walk through this process step by step.
But first, we need to initialize our board. The following few lines of code collect our inputs:
We want a 50 by 50 sized board.
The pad variable makes it easier to calculate neighbors. By padding the edges with extra cells that are always empty, we make it so that we don’t need to write extra logic to handle the edges of the board. So our 50 by 50 board is surrounded by a border of empty cells, making the actual numpy array have a size of 52 by 52.
The initial_cells variable is how many organisms we want to start the board off with. They will be placed randomly on the board.
# Input variables for the boardboardsize = 50        # board will be X by X where X = boardsizepad = 2               # padded border, do not change this!initial_cells = 1500  # this number of initial cells will be placed                       # in randomly generated positions
Next we randomly generate a bunch of coordinates (we chose 1,500 above) where our initial organisms will live. These coordinates are stored in the variable pos_list.
# Get a list of random coordinates so that we can initialize # board with randomly placed organismspos_list = []for i in range(initial_cells):    pos_list.append([random.randint(1, boardsize),                      random.randint(1, boardsize)])
Then it’s time to instantiate the board. We will use a numpy array named my_board to represent our board — we start off with a 52 by 52 array of zeros (it is bigger than 50 by 50 because of the padding) and then call the function init_board() to fill it with organisms according to the coordinates in pos_list. I won’t go into detail on the helper functions here, but they are documented on my GitHub.
# Initialize the boardmy_board = np.zeros((boardsize+pad, boardsize+pad))my_board = init_board(pos_list, my_board)
The part that we’ve been waiting for — animation! First, we need to get some formalities out of the way. The following lines of code create the matplotlib figure that will display our animation.
# Required line for plotting the animation%matplotlib notebook# Initialize the plot of the board that will be used for animationfig = plt.gcf()
Time to make our first frame. The function imshow() from matplotlib takes in a numpy matrix and renders it as an image. Pretty cool!
# Show first image - which is the initial boardim = plt.imshow(my_board)plt.show()
The variable we pass imshow() is our initial board, which is stored in my_board. The image created looks like this:
Now we need to make a helper function that FuncAnimation() can call. The function animate() takes in frame, which is just a counter. The frame counter is how FuncAnimation() communicates with the animate() function — for each step in time (a.k.a. frame), it will call animate() once. And animate() will in turn use the helper function update_board() to iterate the board by one turn. Finally, the function set_data() updates our image with the iterated board and we are good to go.
# Helper function that updates the board and returns a new image of# the updated board animate is the function that FuncAnimation callsdef animate(frame):    im.set_data(update_board(my_board))    return im,
Hurray! We are ready to call FuncAnimation(). Notice the inputs:
fig is the plot variable we created earlier to house our animation.
animate is our function that FuncAnimation() communicates with using the frame counter (it is automatically passed and doesn’t need to be explicitly specified).
frames is how many frames we want the animation to last for, in this case we want our animation to be 200 frames long.
interval is the delay between frames in milliseconds. So we want 50 milliseconds between frames here.
# This line creates the animationanim = animation.FuncAnimation(fig, animate, frames=200,                                interval=50)
And that’s it! Not too bad right? To celebrate our successful animation, here is another gif:
I hope you find this useful. Before I go, let me help brainstorm some more data science-like applications of the animation functionality we learned today:
Drawing out Monte Carlo simulations one by one so you can observe how the outcome distribution is gradually formed.
Walking forward through time series data in order to depict how your model or data reacts as new observations arrive.
Highlighting how the clusters identified by your algorithm shift as you change the inputs such as number of clusters.
Correlation heatmaps over time or across different subsamples of your data to visualize how different samples might affect your model’s estimated parameters.
Cheers!
More from me:
Thoughts on data science.
The random forest algorithm.
How neural networks work.
Logistic regression explained.