Creating Movies with PyPlot/PyLab

Recently, I have been trying to learn more about NumPy, SciPy, and PyLab. So far, I love these libraries. However, there doesn’t seem to be a good way to create movies/animations.

The best way to create a movie using Python is to generate plots using PyLab or PyPlot and save them as pictures. You can then use another program to stitch them together (ie. mencoder or ffmpeg). This process takes substantial amount of time and seems a little bit hacky at best. Please leave comments if you know of a better way.

It took some time to figure out how to get everything configured on MacOS X. My first problem was trying to get a copy of mencoder or ffmpeg. We need one of these programs in order to stitch all the pictures together. I found an interesting post which allowed me to easily install ffmpeg onto my mac. You can download my code and a copy of ffmpeg here.

Once you downloaded the zip file, you will need to

  1. Copy ffmpeg to /usr/local/bin
  2. Execute the following commands from your terminal:
    sudo chown root:wheel /usr/local/bin/ffmpeg
    sudo chmod 755 /usr/local/bin/ffmpeg

Once you have installed ffmpeg, we can look at how to create a movie. I created a function called CreateMovie which will easily create a movie

def CreateMovie(plotter, numberOfFrames, fps=10):
	import os, sys

	import matplotlib.pyplot as plt
 
	for i in range(numberOfFrames):
		plotter(i)

		fname = '_tmp%05d.png'%i
 
		plt.savefig(fname)
		plt.clf()
 
	os.system("rm movie.mp4")

	os.system("ffmpeg -r "+str(fps)+" -b 1800 -i _tmp%05d.png movie.mp4")
	os.system("rm _tmp*.png")

This function creates a movie called movie.mp4 in the current working directory which has a default frame rate of 10 frames per second. Make sure that you don’t have any files called movie.mp4 and _tmp*.png in the current working directory because they will be deleted.

The function takes the following parameters:

plotter: This parameter is a function with the following form:

def plotter(frame_number)

where frame_number is the current frame that needs to be plotted using the matplotlib.pyplot library.

numberOfFrames: The total number of frames in the movie.

fps: The frames per second. The default is 10.

In order to illustrate the use of this function, check out this code for a moving gaussian.

import CreateMovie as movie
import matplotlib.pyplot as plt
import numpy as np

 
x = np.linspace(-.5,4,500)
 
# Plots a given frame
def plotFunction( frame ):
	plt.plot(x, np.exp( -10*(x - frame/10.0)**2) )

	plt.axis((-.5,4,0,1.1))
 
movie.CreateMovie(plotFunction, 50)

This code will generate the following movie.