Wednesday, November 15, 2006

Making movies of plots using gnuplot and mencoder

I had to give a presentation last week in which I wanted to show a curve fit at different times during an experiment. Basically I had a two sets of data points for each 2 second interval over 1000 seconds. One of the sets was raw data, and the other was a curve fit to the peak of the raw points. I decided to try and animate the curves by combing a bunch of JPG images into an MPG file, so that I could embed it in PowerPoint.

Note: All of this is done using Linux.

I used gnuplot to produce graphs of each of these data points, but instead of displaying them on the screen, saved them to an svg file:


set terminal svg
set output "calc.svg"
set xlabel "Piezo height (nm)"
set ylabel "Correlation"
set title "calc"
set xrange [ 2400 : 3000 ]
set yrange [ 0.9 : 1 ]
unset key
plot 'calc-raw.dat', 'calc-fit.dat'
The first line tells it to write SVG's, the second gives the filename. The next five lines are graph formatting options and are pretty self explanatory. The next turns off the key on the graph. The last line plots both of the datasets, the raw data and the fit data, on the same plot.

Now, instead of just having one point with data saved as calc-raw.dat and calc-fit.dat, I actually had a whole directory full called 0001-raw.dat, 0003-raw.dat, etc. Each filename corresponded to the time at which the data was taken. To produce an SVG of each of these I used a saved the commands above to a file called "plotcmds" and used the following bash script:

for file in $(ls -1 --color=none *fit.dat);
do
number=$(basename $file -fit.dat);
sed s/calc/$number/g < plotcmds | gnuplot;
convert $number.svg $number.jpg
done;

The first line loops through each of the files in the directory assiging each filename in turn to the variable "file" (getting the names by running ls with the options -1 for one file per line, and with color off as this adds hidden characters which confuses sed) Then the variable "number" is assigned the number part of the filename, by stripping off the end with the basename command. Then the file plotcmds is fed into the command sed, which replaces every instance of "calc" with the value in the variable "number", and this is then given to gnuplot.Afterwards, the file is converted to a JPG.

After running this command I have a bunch of JPG's, called 0001.jpg, 0003.jpg, etc. To convert these to a movie I ran mencoder from the mplayer package:

mencoder mf://*jpg -mf fps=10:type=jpg -ovc lavc -lavcopts vcodec=msmpeg4v2 -oac copy -o output.mpg

Which joins every JPG in the directory into a 10 frame per second, mpeg4 video. It worked great and looked nice and pro-like.

No comments: