|On this page…|
You can create animated sequences with MATLAB® graphics in three different ways:
Save a number of different pictures and play them back as a movie.
Continually erase and redraw the objects on the screen, making incremental changes with each redraw.
Redefine the XData, YData, ZData, and/or CData plot object properties, optionally linking them to data sources (workspace variables) and updating the properties via calls to refreshdata.
Movies are better suited to situations where each frame is complex and cannot be redrawn rapidly. You create each movie frame in advance so the original drawing time is not important during playback, which is just a matter of blotting the frame to the screen. A movie is not rendered in real time; it is simply a playback of previously rendered frames.
The second technique, drawing, erasing, and then redrawing, makes use of different drawing modes supported by MATLAB graphics. These modes allow faster redrawing at the expense of some rendering accuracy, so you must consider which mode to select.
The third approach allows plots to be updated in data driven fashion and handles redrawing plots (if drawnow is called appropriately).
This section provides an example of each technique.
You can save any sequence of graphs and play the sequence back in a short movie. There are two steps to this process:
Use getframe to generate each movie frame. Be sure that your computer is not in screen saver mode when you call getframe. In the event that you are using several virtual desktops, make sure that the desktop on which the MATLAB application is running is visible on your monitor.
Use movie to run the movie a specified number of times at the specified rate.
cdata — Image data in a uint8 matrix. The matrix has dimensions of height-by-width on indexed-color systems and height-by-width-by-3 on truecolor systems.
colormap — The colormap in an n-by-3 matrix, where n is the number of colors. On truecolor systems, the colormap field is empty.
This example illustrates the use of movies to visualize the quantity fft(eye(n)), which is a complex n-by-n matrix whose elements are various powers of the nth root of unity, exp(i*2*pi/n).
for k = 1:16 plot(fft(eye(k+16))) axis equal M(k) = getframe; end
After generating the movie, you can play it back any number of times. To play it back 30 times, type
You can readily generate and smoothly play back movies with a few dozen frames on most computers. Longer movies require large amounts of primary memory or a very effective virtual memory system.
To capture the contents of the entire figure window (for example, to include GUI components in the movie), specify the figure's handle as an argument to the getframe command. For example, suppose you want to add a slider to indicate the value of k in the previous example. The following code introduces a slider on the left side of the figure.
h = uicontrol('style','slider','position',... [10 50 20 300],'Min',1,'Max',16,'Value',1) for k = 1:16 plot(fft(eye(k+16))) axis equal set(h,'Value',k) M(k) = getframe(gcf); end
In this example, the movie frame contains the entire figure. To play the movie so that it looks like the original figure, make the playback axes fill the figure window.
clf axes('Position',[0 0 1 1]) movie(M,30)
When you create a graph the MATLAB figure stores copies of
Data it needs to define x, y, and z
Color values it depicts in the plot object itself (e.g., lineseries, barseries, surfaceplot, etc.)
If the variables that these values represent are removed or changed, the copies of them in plot object are unaffected. However, you can update these copies (the properties XData, YData, ZData, and CData) at any time; when you do, the graph changes to reflect the updates.
Consequently, you can animate graphs by changing axis data. Do one of the following:
Explicitly provide new axis data to a graph by calling set directly, e.g.,
set(obj_handle,'YData',[3 5 8 6 7 0])
Implicitly update a graph when a workspace variable changes value, by first calling set to define a data source for an axis, e.g.,
and then call refreshdata after you or your code updates varname.
obj_handle is a handle to the plot object you want to update or animate. All graph objects have data source properties (at least an XDatasource and a YDatasource; some also have a ZDatasource and a CDatasource) that by default are empty (axis data has no connection to workspace variables).
You make a persistent connection between axis data and a variable using set, as described earlier and illustrated by the following example. When you call refreshdata, the workspace data replaces the axis data and the program redraws the graph.
Calling refreshdata only causes a graph to be redrawn if any of its declared data sources have changed. It updates all axes at the same time, and updates selected plot objects from a calling function's workspace or the base workspace.
As an example, this script calls refreshdata to animate an area graph of the Pythagorean theorem:
c = -pi:.04:pi; cx = cos(c); cy = -sin(c); hf = figure('color','white'); axis off, axis equal line(cx, cy, 'color', [.4 .4 .8],'LineWidth',3); title('See Pythagoras Run!','Color',[.6 0 0]) hold on x = [-1 0 1 -1]; y = [0 0 0 0]; ht = area(x,y,'facecolor',[.6 0 0]) set(ht,'XDataSource','x') set(ht,'YDataSource','y') for j = 1:length(c) x(2) = cx(j); y(2) = cy(j); refreshdata(hf,'caller') drawnow end
The script needs drawnow to display the results at each iteration. When you call refreshdata from the command line or manually set the XData, YData, ZData, or CData of a graph, the plot redraws automatically. One frame from the animation looks like this.
For more information, see the refreshdata reference page.
To program the same animation without using refreshdata, the code becomes
c = -pi:.04:pi; cx = cos(c); cy = -sin(c); figure('color','white'); axis off, axis equal line(cx, cy, 'color', [.4 .4 .8],'LineWidth',3); title('See Pythagoras run!','Color',[.6 0 0]) hold on x = [-1 0 1 -1]; y = [0 0 0 0]; ht = area(x,y,'facecolor',[.6 0 0]); for j = 1:length(c) x(2) = cx(j); y(2) = cy(j); set(ht,'XData',x) set(ht,'YData',y) drawnow end
This code directly assigns plot axis data. Because there is less evaluation going on, it runs visibly faster. The advantage to using refreshdata is that it makes it easier for a program to keep plots in sync when workspace data changes.
The linkdata function, which you can activate and deactivate with the Data Linking tool on the figure toolbar, is another way to update a graph when any of its data sources change. When it is turned on, the tool updates axis data continuously and automatically, without calling refreshdata. However, data linking is not intended to animate plots; rather, its purpose is to keep different plots in sync and to extend the capabilities of Data Brushing mode, in which you manually highlight observations of interest on a plot. When you use data brushing and data linking together, highlighting observations on one plot causes them to highlight on other plots which display XData, YData, or ZData from the same data sources.
Data linking is not useful for animation because it does not update plots immediately when data source value changes. Instead, it batches updates at roughly half-second intervals to reduce the communications involved in keeping plots and workspace variables synchronized. Therefore, you should not be using data linking at the same time you animate graphs using either of the techniques described above.