Creating Movies with PyPlot/PyLab
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
- Copy ffmpeg to /usr/local/bin
- 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:
where frame_number is the current frame that needs to be plotted using the matplotlib.pyplot library.
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.