Animation

Table of Contents, Get code for this tutorial

Note: You can execute the code from this tutorial by highlighting them, right-clicking, and selecting "Evaluate Selection" (or hit F9).

In this tutorial, you will learn how to do animations in MATLAB. You will learn about creating animations of MATLAB graphs as well as making AVI movies and animated GIFs.

Contents

Animating using Loops

You can easily create animations by using for loops (or while loops). At each loop iteration you can update the graph with the appropriate data for that time step.

m = 1;         % mass
L = 1;         % link length
theta1 = 3*pi/4; % initial angle for theta 1 (in rad)
theta2 = 3*pi/8; % initial angle for theta 2 (in rad)
t = linspace(0, 10, 300);  % simulate for 10 seconds with 300 points

% Solving ODE of a double pendulum
[T,Y] = ode45(@(t, x) double_pendulum(t, x, m, L), ...
   t, [theta1, theta2, 0, 0]);

% Calculating joint coordinates for animation purposes
x = [ L*sin(Y(:,1)),  L*sin(Y(:,1))+L*sin(Y(:,2))];
y = [-L*cos(Y(:,1)), -L*cos(Y(:,1))-L*cos(Y(:,2))];

% Convert radians to degrees
ang = Y(:,1:2)*180/pi;

figure;
subplot(2,1,1);
xlabel('time (sec)'); ylabel('angle (\circ)');

tic;    % start timing
for id = 1:length(T)
   % The top plot shows a time series of link angles
   subplot(2,1,1);
   plot(T,ang, 'LineWidth', 2);
   line(T(id), ang(id,1), 'Marker', '.', 'MarkerSize', 20, 'Color', 'b');
   line(T(id), ang(id,2), 'Marker', '.', 'MarkerSize', 20, 'Color', [0 .5 0]);
   xlabel('time (sec)'); ylabel('angle (deg)');

   % The bottom plot shows the animation of the double pendulum
   subplot(2,1,2);
   plot([0, x(id,1);x(id,1), x(id,2)], [0, y(id,1);y(id,1), y(id,2)], ...
      '.-', 'MarkerSize', 20, 'LineWidth', 2);
   axis equal; axis([-2*L 2*L -2*L 2*L]);
   title(sprintf('Time: %0.2f sec', T(id)));

   drawnow;
end
fprintf('Animation (Regular): %0.2f sec\n', toc);
Animation (Regular): 9.02 sec

Animating using Loops (Smart updating)

While it's perfectly fine to do animations like above, there's a better way of doing animation that is more efficient in terms of memory and speed. Some commands do a lot more than what the name suggests. For example, plot may clear previous axes, remove existing graphics objects, reset some properties, and generate new graphics objects. Doing all of these actions every time through the loop may start to slow down the process especially if you are animating large amounts of data.

A better approach is to do the main plotting once, and then simply change the underlying data through the loop. To do that, you store the handles from the initial plotting routines, and use them to modify the XData and YData.

figure;
subplot(2,1,1);
plot(T, ang, 'LineWidth', 2);
hh1(1) = line(T(1), ang(1,1), 'Marker', '.', 'MarkerSize', 20, 'Color', 'b');
hh1(2) = line(T(1), ang(1,2), 'Marker', '.', 'MarkerSize', 20, 'Color', [0 .5 0]);
xlabel('time (sec)'); ylabel('angle (deg)');

subplot(2,1,2);
hh2 = plot([0, x(1,1);x(1,1), x(1,2)], [0, y(1,1);y(1,1), y(1,2)], ...
      '.-', 'MarkerSize', 20, 'LineWidth', 2);
axis equal
axis([-2*L 2*L -2*L 2*L]);
ht = title(sprintf('Time: %0.2f sec', T(1)));

tic;     % start timing
for id = 1:length(T)
   % Update XData and YData
   set(hh1(1), 'XData', T(id)          , 'YData', ang(id, 1));
   set(hh1(2), 'XData', T(id)          , 'YData', ang(id, 2));
   set(hh2(1), 'XData', [0, x(id, 1)]  , 'YData', [0, y(id, 1)]);
   set(hh2(2), 'XData', x(id, :)       , 'YData', y(id, :));
   set(ht, 'String', sprintf('Time: %0.2f sec', T(id)));

   drawnow;
end
fprintf('Animation (Smart update): %0.2f sec\n', toc);
Animation (Smart update): 3.22 sec

If it's too fast, you can always put a pause command instead of drawnow.

Animation using Timer Objects

Instead of using loops, you can also create animations using MATLAB's timer objects. Timer objects are a generic way of performing scheduled actions. One of the advantages of using a timer object is that it allows you to do other operations in MATLAB in between timer executions. The documentation does a good job explaining how to use timer objects. You basically put the graphics update code inside the timer function that gets executed every time interval.

Creating Movies (AVI)

Once you have an animation working in MATLAB, you can easily create a movie file (AVI) using avifile or movie2avi.

% Preallocate movie structure.
mov(1:length(T)) = struct('cdata', [], 'colormap', []);

% Animate and add animation frame to the movie structure
for id = 1:length(T)
   % Update XData and YData
   set(hh1(1), 'XData', T(id)          , 'YData', ang(id, 1));
   set(hh1(2), 'XData', T(id)          , 'YData', ang(id, 2));
   set(hh2(1), 'XData', [0, x(id, 1)]  , 'YData', [0, y(id, 1)]);
   set(hh2(2), 'XData', x(id, :)       , 'YData', y(id, :));
   set(ht, 'String', sprintf('Time: %0.2f sec', T(id)));

   % Get frame as an image
   mov(id) = getframe(gcf);
end

% Create AVI file
movie2avi(mov, 'animation.avi');

clear mov

Creating Animated GIFs

Another way to save the animation is to create an animated GIF. You can create one using the imwrite function.

% Get figure size
pos = get(gcf, 'Position');
width = pos(3);
height = pos(4);

% Preallocate
mov = zeros(height, width, 1, length(T), 'uint8');

% Animate and add animation frame to the movie structure
for id = 1:length(T)
   % Update XData and YData
   set(hh1(1), 'XData', T(id)          , 'YData', ang(id, 1));
   set(hh1(2), 'XData', T(id)          , 'YData', ang(id, 2));
   set(hh2(1), 'XData', [0, x(id, 1)]  , 'YData', [0, y(id, 1)]);
   set(hh2(2), 'XData', x(id, :)       , 'YData', y(id, :));
   set(ht, 'String', sprintf('Time: %0.2f sec', T(id)));

   % Get frame as an image
   f = getframe(gcf);

   % Create a colormap for the first frame. For the rest of the frames, use
   % the same colormap
   if id == 1
      [mov(:,:,1,id), map] = rgb2ind(f.cdata, 256, 'nodither');
   else
      mov(:,:,1,id) = rgb2ind(f.cdata, map, 'nodither');
   end
end

% Create animated GIF
imwrite(mov, map, 'animation.gif', 'DelayTime', 0, 'LoopCount', inf)

Table of Contents