How to play an AVI file and display a for loop animation in a single figure window?

1 view (last 30 days)
I am working on displaying an AVI video file and an animated plot that uses the line() command and a for loop in one figure window. Is there any way that I can display these animations in the same figure and have them sync up with the same time step?
Here is an example of my code:
clc
clear all
close all
set(gca,'position',[0, 0, 0.75, .75])% I think this is used to help allign the subplot in the figure
for t = 1:100 %This helps generate the time vector
subplot(223);
%These are the equations used for plotting in the animated figure
%window
m(t) = -1 + sin(t) .* log(t);
n(t) = 1 -log(t);
o(t) = (n(t) + m(t)) ./ 2;
%This sets the initial axis values for the figure before the axese
%begin to move
xlim([0 25]); % placed 3 more "0's" at the end of the numerals 5/27/2016
ylim([-5 5]); % placed 3 more "0's" at the end of the numerals 5/27/2016
%This is used to display the markers on the data plots for the viewer
%to see some pretty colors:)
line(1:t, m(1:t), 'Marker', '.', 'Color', 'r');
line(1:t, n(1:t), 'Marker', '.', 'Color', 'b');
line(1:t, o(1:t), 'Marker', 'd', 'Color', 'c', 'LineWidth', 1.5);
drawnow %this helps the little chill'ens draw the plot on the matlab figure right this very moment. It is very touching:)
hold on %This keeps the figure open to hold the next figure when it shows up
if t>25 % 2.5 is the time marker that starts moving the scales along with the data as it travels across the screen
xlim([0, t]); %This is used to make the x-axis move after the time data point has reached a particular distance along the graph t + 5 - (t) .^ (.5)
ylim([-10, 10]);
else t >= 95; %this is used for the signal point where the x-axis no longer moves
xlim([0, t]); %This is used to make the x-axis move after the time data point has reached a particular distance along the graph t + 5 - (t) .^ (.5)
ylim([-10, 10]);%This keeps the y-axis the same throughout the graph
end
pause(.25);%This helps pause the video for ease of viewing
f = getframe(gcf);%This captures the immediate frame for further use
G(t) = [f];%This stores the image files in a data structure to be aid in the creation of the movie
clf %I don't know what this does exactly
% writeVideo(fuzzy_bunny.gif,F(t));
end
set(gca,'XtickLabel',[],'YtickLabel',[]);% This is used to eliminate the axis labels for the subplot
set(gca,'position',[0 0 1 1]); % This sets the position of the suplot in the figure window
movie(G) % the movie is approximately 9 to 10 seconds long
movie2avi(G, 'fuzzy_bunny.avi'); %This is used to create the file "fuzzy_bunny.avi"
Thanks for your help!

Answers (1)

Philipp Tempel
Philipp Tempel on 10 Jun 2016
Darth, I checked your code. There's at least one error in it, but also a few things I'd do differently. So here's the list:
Error: On line 26 you have
else t >= 95
this won't work as the argument to else won't be evaluated (default if-else behavior). I pressume you wanted an
elseif t >= 95
What I usually do to animate data (either for a video or for on-screen display of time-dependent data) is
1) Pre-process the data such that you can use it right away for the plot. That is e.g., if you have a multi-body system and use relative coordinates, then you cannot use that for plotting. So you need to first transform relative data to absolute data. You also want to determine the maximum axes limits (if you don't want your axes to scale with more data being added). In your case that would include moving all
m(t) = -1 + sin(t) .* log(t);
n(t) = 1 -log(t);
o(t) = (n(t) + m(t)) ./ 2;
xlim([0 25]); %
ylim([-5 5]); %
out of the for-loop.
2) Determine your FPS you want to have and from that create a vector of timesamples i.e.,
fps = 25;
tVideo = 0:1/fps:tEnd;
3) This only applies to data that has no constant time-difference in it from e.g., a variable step-size solver. You want to find the state of the system closest to your video timestamps. Code could look like this
% Get the vector of frames we need to extract
vFrames = zeros(numel(tVideo), 1);
% This might also work as a vectorized function call
for iFrameTime = 1:numel(tVideo)
vDiff = abs(vTime - tVideo(iFrameTime));
vFrames(iFrameTime) = find(vDiff == min(vDiff), 1, 'first');
end
Using vFrames you can then find the closest data sample for the current timestep of your simulation. That is, you loop over all vFrames with iFrame loop-index and just plot whatever you have in e.g., x(vFrames(iFrame))
4) There is no need to use pause in the loop of movie creation. You can just draw everything - most of the times you have quite a heavy plot so that drawnow takes some time anyway.
5) Take a frame of the current figure and store it into the video using
frame = getframe(hfig);
writeVideo(writerObj, frame);
And one tip
Try to limit your plotting for animation or videos to the bare minimum you need. Also, try to avoid resetting the plot by clf or akin. You would want to have a handle to the plot and then update it using
hPlot.XData = newXData;
hPlot.YData = newYData;
hPlot.ZData = newZData; % in case you have 3D-data
To get back to your question: I only saw one plot in my figure as I was running your code. If you have multiple subplots (as it seems from your code), then you would want to get handles to the subplots' axes or to the plots themselves inside there and then update them setting their XData properly. For that you might want to know that you can create an empty plot using
hPlot = plot(NaN, NaN);
You could then store all your plot handles in an array (be aware that plot returns an array if you're plotting more than one variable i.e., matrices) and update them as you are looping over time. Here again: do all the pre-processing i.e., data determination such as x = f(t) and y = f(t) before you plot. This way you can speed up rendering the result (though waiting for the figure to pop open takes a bit longer).
If you have any follow-up questions or if I didn't answer your correction completely, just hit me up again!

Categories

Find more on Animation in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!