MATLAB animations

From Fluids Wiki
Jump to navigation Jump to search

There are many ways to generate animations of data from MATLAB. This page describes two relatively painless approaches.

Creating sequentially named frames

First you will need to create a bunch of frames in MATLAB and save them with sequential file names. For example if you are saving PNG files, you should have something like frame0001.png, frame0002.png, etc. Example MATLAB code to generate files follows:

figure(1); clf; set(gcf,'renderer','zbuffer');
for ii=1:10
  pcolor(randn(20));
  shading flat;
  filename=sprintf('frame%05d.png',ii);
  print('-dpng', '-r100', filename);
end


This is example code that generates random pictures. You can of course fine tune your frames. For example, set the size as described in MATLAB figures and specify what dpi to use, and hence control your frame size.

Option 1: Creating an AVI file

First create sequentially named PNG files, then run mkavi.sh in the directory with the PNG files. The code for mkavi.sh follows:

#!/bin/bash
# mkavi.sh - Create a DIVX movie from a bunch of PNG frames, store it in an AVI container.
#          - Requires mencoder.

# set frame rate
FPS=8
# set bitrate, larger = better quality but larger file
BITRATE=1000

# this should not be changed
THREADS=1
PASS=2

# Make an MPEG-4 file and put it in an AVI container for Windows playback
AVCOPTS="vcodec=mpeg4:vbitrate=$BITRATE:threads=$THREADS"
FOURCC=DIVX
if [ $PASS -eq 1 ]; then
  mencoder "mf://*.png" -mf fps=$FPS -o movie.avi -ovc lavc -ffourcc $FOURCC -lavcopts $AVCOPTS
else
  mencoder "mf://*.png" -mf fps=$FPS -o /dev/null -ovc lavc -ffourcc $FOURCC -lavcopts $AVCOPTS:vpass=1
  mencoder "mf://*.png" -mf fps=$FPS -o movie.avi -ovc lavc -ffourcc $FOURCC -lavcopts $AVCOPTS:vpass=2
  rm -f divx2pass.log
fi

Option 2: Creating an animated GIF file

Creating an animated GIF file has two components. The first is to create individual GIF files for each frame of the animation. This requires conversion because MATLAB does not directly support GIF output.

Converting a single frame to GIF

To convert a single frame to a GIF, execute the command

convert {NAME}.png {NAME}.gif

where {NAME} is the file-name of the frame saved from MATLAB, as in Option 1. E.g.,

convert frame005.png frame005.gif

This uses the 'convert' utility from ImageMagick to do the conversion. Usually it does the right thing.

This can be done inside of MATLAB by using the 'system' command:

figure(1); clf; set(gcf,'renderer','zbuffer');
for ii=1:10
  pcolor(randn(20));
  shading flat;
  %% Generate a PNG file output, written to its own directory
  filename=sprintf('PNG_FRAMES/frame%05d.png',ii);
  %% Generate the equivalent GIF filename
  gif_filename = sprintf('GIF_FRAMES/frame%05d.gif',ii);
  print('-dpng', '-r100', filename);
  %% Execute convert to do the format conversion
  system(sprintf('convert %s %s',filename,gif_filename));
end

Generating the animated GIF

Once the sequential frames are generated and converted into the GIF format, the convert utility can also be used to produce the final animated GIF file. To do this, execute the command:

convert -delay 5 -loop 0 GIF_FRAMES/frame*.gif ./movie.gif

where this assumes that the frames are stored in the 'GIF_FRAMES' subdirectory, as in the example above. The parameters to convert used here are 'delay', which is the time between frames in 1/100ths of a second, and 'loop', which specifies whether or not the animation should loop upon completion. This example generates a movie that runs at 20 frames per second (100/5) and does not loop upon completion.

File optimization

Sometimes, the animated GIF generated by 'convert' is extremely large; 10MB and up is not uncommon. In some cases, this file size can be greatly reduced by using the GIF optimization program 'gifsicle'. To use this, simply execute:

gifsicle --optimize=2 --colors=256 < input_movie.gif > optimized_movie.gif

where 'input_movie.gif' and 'optimized_movie.gif' refer to the appropriate files.