# Matlab animations tutorial Below is a PDF of my presentation and the code for a tutorial on making elaborate multi-axes movies with Matlab. The tutorial was part of the "hallway salon" series that has become a tradition in the Daniel Lab.

The code contained on this page contains a framework for saving movies from MATLAB that should be easily adaptable for your own work. I tried to add as many comments in the code, so it should be fairly self-explanatory.

### Code output: an AVI file

The embedded video below shows you the output of the code featured on this page. (It's of much lower quality than the AVI file you would get on your computer by running the script.)

### MATLAB code in chunks

Copy the following pieces of code into your MATLAB editor. You should create two new m files. Copy cells 1 to 4 (below) into one document, saved as something like "myanimation.m". The other file has to be named "plotfilledcircle.m". This is a helper function for plotting a circle.

#### Cell 1: Creating data for our animation

This piece of code just creates the path for our circle to move along; a simple spiral. There are two vectors, xpos and ypos, that contain the center coordinates of our circle for each frame. The last line in the listing below creates a vector that defines the circle's radius for each frame.
`%% Create test data for our animation: a dot moving along a path% Our aim is to make a circle move around an image along a specified path.% First, we'll create that path (xpos and ypos) revolution_no = 5;         % how often around the circleang_resolution = 40;       % how many points (i.e. frames) per circleda = 2*pi/ang_resolution;  % delta angle t = 0:da:revolution_no*2*pi;            % time steps % why not a spiral:pathradius = linspace(0,10,length(t));  % path radius increases each dtxpos = pathradius.*cos(t);ypos = pathradius.*sin(t); % show what we have so far:figure(1);subplot(1,3,1:2)plot(t,xpos, '-k'); hold on;plot(t,ypos, '-r');set(gca, 'XLim', [0 max(t)]); box off;xlabel('time steps');  ylabel('x (black) and y (red) pos') subplot(1,3,3)plot(xpos,ypos,'k'); axis equal; axis off;title('The path our circle will move along'); % We now want to use these x-y coordinates to place a cirle on an image.% Each iteration, we want the position to be updated so that it appears as% if the circle moved around the specified path.% In addition, we want the circle diameter to change as it goes along. circlesize = linspace(0.2,2, length(t)); % circle size increases linearly`

#### Cell 2: Plotting a circle that moves along the path specified above

This piece of code draws a circle on a figure with white background. It allows us to check whether everything looks OK, before going to the next cell in which we'll save the result of each iteration into a TIFF stack. This code depends on the helper function called "plotfilledcircle". Copy the code for this function (found a few paragraphs further down) into it's own m file. It has to be saved with the function's name (plotfilledcircle.m) and should either be in the same directory as your other m file, or in a directory that MATLAB knows about (i.e. in its path).
`%% Test the moving circle and save it as an image sequence% We'll now plot a circle for each time steps, according to the path and% size specifications above. I created a separate function to create the% circle, called 'plotfilledcircle'. axlim = 100;figure('Position', [100 100 400 400]); % match goal dimensions;for c = 1:length(t)    fprintf('Frame: %03d\n', c); % display counter     ph = plotfilledcircle(circlesize(c), [xpos(c) ypos(c)]); % plot circle    axis off;    % we need to set the axes to an appropriate limit, otherwise they'll    % resize to always show the full circle:    axis([-axlim axlim -axlim axlim]);    axis square;     pause(0.05); % pause a bit to see animationend`

#### Cell 3: same as cell 2, but now we save an image sequence

`%% Same as above, but now we save it as an image sequence (TIFF stack)% axlim = 15;figh=figure('Position', [100 100 400 400]); % match goal dimensionsfor c = 1:length(t)    fprintf('Frame: %03d\n', c); % display counter     ph=plotfilledcircle(circlesize(c), [xpos(c) ypos(c)]); % plot circle    axis off;    % we need to set the axes to an appropriate limit, otherwise they'll    % resize to always show the full circle:    axis([-axlim axlim -axlim axlim]);    axis square;     % We'll save this animation as a tiff stack, so we can load it    % back later for our grand finale    currentframe = frame2im(getframe(figh)); % convert fig into image data    currentframe = im2bw(currentframe,0.4); % make it binary to save space    pause(0.1); % added to prevent skipped frames    if c == 1        imwrite(currentframe, 'tiffstack.tiff', 'WriteMode', 'overwrite');    else        imwrite(currentframe, 'tiffstack.tiff', 'WriteMode', 'append');    end     pause(0.2); % pause a bit to see animationend`

#### Cell 4: Putting it all together to make a multi-axes figure and save an AVI file

The following, long piece of code is the recipe for creating a movie file that I use. There are multiple ways of doing this, but using the avifile() and addframe() functions works well for me...
`%% Putting it all together % We now want a fancy animation that includes the circle object, as well% as its position and size data in the form of 'evolving' graphs.%% At this point you should think about what resolution your final movie% might have. This depends on what you want to do. If you need a full-size% slide for an animation, you might as well just create the animation at% that size. Chances are, it looks better if PowerPoint doesn't have to% scale the movie.% If it's for an HD segment of a movie, use HD sizes (eg. 720p: 1280x720px% or 1080p: 1920x1080px). HD will result in HUGE movie files if no% compression is used. Here we'll use 1024x768 pixels, which is the native% resolution of many projectors and the default on my Keynote documents.%% We also want to think about where to place the individual graphs% It helps to draw it out on a piece of paper.% For the purpose of this tutorial, we want four axes:% 1) fill plot of the circle (just like above, but with diff. colors)% 2) plot of the images we exported above% 3) evolving graph of the circle size% 4) evolving graph of the circle's X and Y position%% I like to start by setting up the positions of all those elements: fig_pos = [100 40 1024 768]; % position and size of the figure window fillplot_ax_pos = [80 320 400 400];        % position and size of fill plotimage_ax_pos = [580 320 400 400];          % image plotaxlim = 15;sizedata_ax_pos = [50 170 1024-60 70];     % circle size graphposdata_ax_pos = [50 50 1024-60 100];      % circle position graph % It's also often useful to define all the colors with variables set up% top: fig_col = [1 1 1];  % figure background colortext_col = [0 0 0]; % text colorlight_grey = [.4 .4 .4];dark_grey = [.2 .2 .2];nice_blue = [51/255 51/255 102/255];light_red = [.6 .4 .4];  % I like to have a little if-statement, so that only when I set a flag to 1% will a movie file be created. Set to zero for setting stuff up. When% you're ready, set it to one.movieflag = 0;moviefilename = 'tutorialmovie.avi'; % only if our flag is set to 1, will we open up a movie object:if movieflag == 1    aviobj = avifile(moviefilename, 'fps', 15, 'compression', 'none');end startframe = 100; endframe = 120; % which frames to plot (useful for debugging)% startframe = 1; endframe = length(t); % complete loop fh= figure('color', fig_col, 'name', 'Tutorial animation movie', ...    'Position', fig_pos);tic;fprintf('\nWe are entering the loop...\n');% ***************  START THE BIG LOOP AFTER CREATING FIG. ***************for k = startframe:endframe     titlestr = sprintf('Frame: %03d', k); % our title will change    fprintf('Frame %d\n', k); % print loop counter      % ***************  1) FILL PLOT AXES ***************    fillplot_ax = axes;    set(fillplot_ax, 'Units', 'pixels', 'Position', fillplot_ax_pos);     p1h(1)=plot(xpos,ypos, '-.');    set(p1h(1), 'Color', light_grey);    hold on;     p1h(2) = plotfilledcircle(circlesize(k), [xpos(k) ypos(k)], nice_blue); % plot circle     p1h(3) = line([0 xpos(k)], [0 ypos(k)]);    set(p1h(3), 'Color', light_red, 'LineWidth', 3);    hold off;    % we need to set the axes to an appropriate limit, otherwise they'll    % resize to always show the full circle:    axis([-axlim axlim -axlim axlim]);    axis square;    th=title(titlestr);    xlabel('x pos'); ylabel('y pos');    set(th, 'FontSize', 14); % make title font larger      % ***************  2) TIFF IMAGE IMPORT PLOT AXES ***************    image_ax = axes;    set(image_ax, 'Units', 'pixels', 'Position', image_ax_pos);    try        img = imread('tiffstack.tiff', k); % load image of current index    catch ME1        % Get last segment of the error message identifier.        idSegLast = regexp(ME1.identifier, '(?<=:)\w+\$', 'match');        disp(idSegLast);        error('Failed loading tiff image');            end    img = xor(1,img); % invert image to make it more exciting... XOR rules!    imagesc(img);  colormap gray;    axis off; axis image;     th=title('Inverted image from TIFF stack');    set(th, 'FontSize', 14);       % *************** 3) SIZE DATA PLOT AXES ***************    sizedata_ax = axes;    set(sizedata_ax, 'Units', 'pixels','Position', sizedata_ax_pos);     p2h(1)=plot(t,circlesize,'--');    set(p2h(1), 'Color', light_grey, 'LineWidth', 1);    %  create evolving data graph:    hold on;    p2h(2)=plot(t(1:k),circlesize(1:k),'-');    set(p2h(2), 'Color', nice_blue, 'LineWidth', 2);     hold off;    ylabel('dot size','fontsize',12);     set(sizedata_ax, 'XLim', [0 max(t)]);    set(gca, 'FontSize', 12);      % *************** 4) POSITION DATA PLOT AXES ***************     posdata_ax = axes;    set(posdata_ax, 'Units', 'pixels', 'Position', posdata_ax_pos);     p3h(1)=plot(t,xpos,'-.');    set(p3h(1), 'Color', light_grey, 'LineWidth', 1);    hold on;    p3h(2)=plot(t,ypos,'--');    set(p3h(2), 'Color', light_red, 'LineWidth', 1);     p3h(3)=plot(t(1:k), xpos(1:k),'-');    set(p3h(3), 'Color', dark_grey, 'LineWidth', 2);     p3h(4)=plot(t(1:k), ypos(1:k),'-');    set(p3h(4), 'Color', light_red, 'LineWidth', 2);    set(posdata_ax, 'XLim', [0 max(t)]);     xlabel('time','fontsize',12); ylabel('dot pos','fontsize',12);     % Hack to move xlabel in line with the upper one (try without):    ylabh = get(gca,'YLabel');    set(ylabh,'Position', get(ylabh,'Position') + [.4 0 0]);     set(gca, 'FontSize', 12);       % ***************  FINISH THE FRAME (AVI if selected)  ***************    pause(.2);    if movieflag == 1        frame = getframe(gcf);           % capture current figure        aviobj = addframe(aviobj,frame); % use addframe to append frame    end    if k < endframe        clf; % clear figure except for very last frame    end end % of the big loopfprintf('\nDone looping...\n'); if movieflag == 1    fprintf('Saving movie...\n\n');    aviobj = close(aviobj);endtoc`

#### Helper function: plotfilledcircle.m

Save this file as "plotfilledcircle.m".
`function ph = plotfilledcircle(circle_radius,circlecenter, fcol)%% plotfilledcircle(circle_radius,circlecenter, fcol)    %% Function to plot a filled circle with radius 'circle_radius'% 'circlecenter' ... center location [0 0] is default% 'fcol' is optional and defines the face color (black default)% % Armin H 2011 if nargin < 2    circlecenter = [0 0];endif nargin < 3    fcol = [0 0 0];    end theta = linspace(0,2*pi,100); % 100 points between 0 and 2pix = circle_radius*cos(theta) + circlecenter(1);y = circle_radius*sin(theta) + circlecenter(2);ph = fill(x, y, 'k');set(ph, 'FaceColor', fcol);box off;  axis equal; end`
Category:
Code
File attachments: MATLAB-animatedPlotsTutorialArmin.pdf