Creating Animated Plots in MATLAB
This tutorial will demonstrate how to create animated plots using MATLAB. This will be demonstrated through the use of a Fourier approximation of a square wave. The infinite series representing the Fourier approximation of a square wave is:
We will now create an animated GIF showing the first 20 terms in this Fourier approximation. For this plot, the only information that changes for each series in title and the y-data for the Fourier approximation. This can be handled efficiently by only updating that information for each iteration of the loop.
%% Define waveform properties f = 1; % Frequency (Hz) t = 0:.001:2; % Eval time (s) Y_Fourier = zeros(size(t)); % Preallocate %% Generate the frames for k = 1:20; Y_Fourier = (4/pi)*sin(2*pi*(2*k-1)*f*t)/(2*k-1) + Y_Fourier; if k == 1 % Only create the plot for 1st iteration, update wave for % subsequent figure(); hold('on'); grid('on'); ylim([-1.5 1.5]); set(gca, 'xtick', 0:0.5:2); h1 = plot(t, square(t*2*pi), 'LineWidth', 2); h2 = plot(t,Y_Fourier, 'LineWidth', 2); legend('Square Wave (1 Hz)', 'Fourier Approximation'); xlabel('Time (s)'); ylabel('Amplitude'); else % Update y data set(h2, 'ydata', Y_Fourier) end title(['k = ' num2str(k)]);
Creating the frames
To create the frames for the animated GIF, we will save each plot of the Fourier approximation to a *.png file. It is possible to create an animation without first saving the frames to files by using the getframe() function within MATLAB. However, this method allows for easier control over the animation resolution as well as works in cases where the frames were created using other means, e.g. images obtained from a camera.
Each frame will be generated using the print() function. The necessary inputs for this process is the frame name, the image format, and the image resolution. For this example, the animation will be created with a resolution of 150 PPI. Keep in mind that this animation will be displayed on a screen and images with resolutions greater than the screen resolution will be displayed at the screen resolution.
% Save as png with a resolution of 150 pixels per inch print(['Frame ' num2str(k)], '-dpng', '-r150'); end
Assembling the frames into an animated GIF image
Finally, now that the frames are created, we can assemble the into an animated GIF using the imwrite() command. Two of the necessary inputs for the imwrite command is the image data X and a color scale associated with that data included in map. The GIF image format only supports 8 bit images. If the image being read with imread() is greater than uint8, a conversion may be necessary.
GifName = 'SquareWaveAnimation.gif'; delay = 0.5; % Delay between frames (s) for ii = 1:20 [A, ~] = imread(['Frame ' num2str(ii) '.png']); [X, map] = rgb2ind(A, 256); if ii == 1 imwrite(X, map, GifName, 'gif', 'LoopCount', inf, 'DelayTime', delay) else imwrite(X, map, GifName, 'gif', 'WriteMode', 'append', 'DelayTime', delay) end end
The result
The output from the above code becomes:
Full code
%% Define waveform properties f = 1; % Frequency (Hz) t = 0:.001:2; % Eval time (s) Y_Fourier = zeros(size(t)); % Preallocate %% Generate the frames for k = 1:20; Y_Fourier = (4/pi)*sin(2*pi*(2*k-1)*f*t)/(2*k-1) + Y_Fourier; if k == 1 % Only create the plot for 1st iteration, update wave for % subsequent figure(); hold('on'); grid('on'); ylim([-1.5 1.5]); set(gca, 'xtick', 0:0.5:2); h1 = plot(t, square(t*2*pi), 'LineWidth', 2); h2 = plot(t,Y_Fourier, 'LineWidth', 2); legend('Square Wave (1 Hz)', 'Fourier Approximation'); xlabel('Time (s)'); ylabel('Amplitude'); else % Update y data set(h2, 'ydata', Y_Fourier) end title(['k = ' num2str(k)]); % Save as png with a resolution of 150 pixels per inch print(['Frame ' num2str(k)], '-dpng', '-r150'); end %% Now time to generate the animated gif GifName = 'SquareWaveAnimation.gif'; delay = 0.5; % Delay between frames (s) for ii = 1:20 [A, ~] = imread(['Frame ' num2str(ii) '.png']); [X, map] = rgb2ind(A, 256); if ii == 1 imwrite(X, map, GifName, 'gif', 'LoopCount', inf, 'DelayTime', delay) else imwrite(X, map, GifName, 'gif', 'WriteMode', 'append', 'DelayTime', delay) end end