Save animation as gif in Matlab GUI - matlab

I am trying to save an animation as animated GIF.
My plot is similar to the given code below.
I created it with animated line too.
The problem is that:
When I defined my figure as f=figure or figure(1) it creates the .gif file properly.
However, instead of plotting my figure in separate screen using "figure" command, I have to plot in an axes on MATLAB GUI axes as the given figure.
I tried it with: f=(handles.axes_threeDOF);, But when I use this function, the gif file creates different part of the screen.
Could you help me to solve my problem?
numpoints = 500;
x = linspace(0,4*pi,numpoints);
y = square(x);
y2 = 3 +square(x+1);
f = figure
h = animatedline('Color','b','LineWidth',2);
h2 = animatedline('Color','r','LineWidth',2);
grid on;
axis([0,12,-3,+6])
for k = 1:numpoints
addpoints(h,x(k),y(k))
addpoints(h2,x(k),y2(k))
drawnow
% Capture the plot as an image
frame = getframe(f);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
% Write to the GIF File
if k == 1
imwrite(imind,cm,'test.gif','gif', 'Loopcount',inf);
else
imwrite(imind,cm,'test.gif','gif','WriteMode','append');
end
end
I want to create a gif of this animation:
But it creates as given below with this function " f=(handles.axes_threeDOF)"

I think I found the problem:
f = handles.axes_threeDOF gets the handle of the axes instead of getting the handle of the figure.
Since I don't know the name of your figure, I can't give a perfect solution.
You may try the following options:
1.Find the name of the figure, and use something like: f = handles.figure_threeDOF;
2. Use f = gcf();, assuming there is only one figure.
3. Use f = handles.axes_threeDOF.Parent; assuming the figure is the "Parent" of the axes.
Update:
After im = frame2im(frame);, you need to crop the relevant part of the image:
Something like: im = im(36:884, 928:1800, :);
There are more robust solution than using fixed indices, but it requires some knowledge about the internal structure of the figure.
Here is a code that reproduce the problem (instead of figure handle, f gets axes handle):
numpoints = 500;
x = linspace(0,4*pi,numpoints);
y = square(x);
y2 = 3 +square(x+1);
f = figure;
h = animatedline('Color','b','LineWidth',2);
h2 = animatedline('Color','r','LineWidth',2);
grid on;
axis([0,12,-3,+6])
for k = 1:numpoints
addpoints(h,x(k),y(k))
addpoints(h2,x(k),y2(k))
drawnow
%%% Test %%%
%The following code demonstrates the problem.
%f = gca(), returns a handle to the axes, instead of the figure.
%You should remove the following line for the code to work properly...
f = gca();
%%% Test %%%
% Capture the plot as an image
frame = getframe(f);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
% Write to the GIF File
if k == 1
imwrite(imind,cm,'test.gif','gif', 'Loopcount',inf);
else
imwrite(imind,cm,'test.gif','gif','WriteMode','append');
end
end
Result of correct code (without f = gca();):
Result of wrong code (with f = gca();) - getting axes handle instead of figure handle:

Related

Print figure when plot finishes, works on debug mode but not in runtime

I've used GUIDE to develop a Matlab App that allows loading images and performing analysis on them. In short, I show the image by using imshow and add markers and text (by using plot and text functions respectively). I want to print the figure to a file, including the markers and the text, but strangely it is only printing the original image. On the other hand, when I put a breakpoint before the print command, it works perfectly, so it seems to me that it is a problem of "timing". However, I have tried "drawnow" and "pause(X)" to no avail, so I was wondering whether I'm doing something wrong or there is another way to do this.
This is the pseudo-code which is inside an "updateImage()" function (called by a button):
cla(handles.h_image); %clear image axes. "handles" is a structure created by GUIDE containing handles to all objects in the figure. "handles.h_image" is the handle to the axes of my image
im = imshow(ch_data,'Parent',handles.h_image); drawnow %ch_data contains the image
hold on
for n = 1:length(myarray) % myarray is not actually too big, length of about 100
x1 = whatever; x2 = whatever; y1 = whatever; y2 = whatever;
plot([x1 x2],[y1 y2],'linestyle','-','linewidth',1,'color',[211 99 252]/255);
text(x1, y1, num2str(n),'Fontsize',10,'color',[208 240 255]/255);
end
pause(5) %tried different values, but still not working in runtime
cd(results_dir)
print(handles.container,'-dtiff', '-opengl', '-r300', 'myimagename');
EDIT: I've tried that part of the code on a separate script and it works fine...
f = figure;
im = imshow('peppers.png'); drawnow
hold on
r = randi([1 size(im.CData,1)],1,200);
for n = 1:50
x1 = r(n); x2 = r(n*2); y1 = r(n*3); y2 = r(n*4);
plot([x1 x2],[y1 y2],'linestyle','-','linewidth',1,'color',[211 99 252]/255);
text(x1, y1, num2str(n),'Fontsize',10,'color',[208 240 255]/255);
end
print(f,'-dtiff', '-opengl', '-r300', 'myimagename');
One difference between your two code snippets is that in the first you are saving 'handles.container' while in the other it's a figure handle.
Try
f = ancestor ( handles.h_image, 'figure )
print ( f, ..... )

Matlab animate background and line in same figure

I am trying to animate a line over a dynamic background at the same time, the problem is I cannot update both in the same plot. If I animate the background the lines don't appear.
So the question is why? I was trying in different positions without success.
If you remove the part of the imagesc, there is no problem and the animation of the lines flow
for k = 1:numel(t)
decay = rand;
res = decay * background;
imagesc(x,y,flip(res));
hold on
clearpoints(h);
clearpoints(p);
addpoints(p,[l,(cosO(k)],[0,cosO(k)]);
addpoints(h,[r,(senO(k)],[0,senO(k)]);
drawnow
hold off
end
Fixed! Create a handler and modify CData inside of the loop:
imh = imagesc(x,y,flip(res));
for ...
imh.CData = flip(res);
end
The calls to imagesc overrun your plot. you can overcome this by only change the image matrix represented by imagesc (as 'CData' property):
for k = 1:numel(t)
decay = rand;
res = decay * background;
if k == 1
imh = imagesc(x,y,flip(res));
else
imh.CData = flip(res);
% or: set(imh, 'CData', flip(res) ); % in older MATLAB versions
...
end

MATLAB movie2avi cannot made video

I am trying to test the function movie2avi using simple codes in R2014a as follows:
clear; close all;
figure;
Z = peaks;
surf(Z);
axis tight manual;
ax = gca;
ax.NextPlot = 'replaceChildren';
loops = 40;
F(loops) = struct('cdata',[],'colormap',[]);
for j = 1:loops
X = sin(j*pi/10)*Z;
surf(X,Z);
drawnow;
F(j) = getframe(gcf);
end
movie(F);
movie2avi(F, 'myPeaks.avi', 'compression', 'None');
It seems the movie(F) works well but the avi file created contains the toolbar and background instead of just showing the graph. Also the avi file just show stationary picture as follow:
Using quicktime to open it would produce same result:
https://www.dropbox.com/s/fd8vw7jvll5xkpw/b.png?dl=0
There is also a warning:
Warning: Struct field assignment overwrites a value with class "double". See MATLAB R14SP2 Release Notes, Assigning Nonstructure
Variables As Structures Displays Warning, for details.
Please help. Thanks.
Have you tried
F(j) = getframe(gca); %// Gets the current axis
This will capture the axis rather than the entire figure window.

Animate surface plot in Matlab

I have a matrix representing height of a 10x10 square grid over time. The height is updated in a for loop over the rows and columns. My attempt was to simply put the surf(height) within the this loop, with a 0.1 second pause between plots, because this is how I done it with a 2-d plot. How can I make this work?
I think the best way is to update the data directly from your surface plot.
To do so, assign it a handles (eg. named hSurf) during its creation and then update the ZData property using, for example,
set(hSurf,'ZData',SomeValues)
Sample code:
clear
clc
close all
figure(1)
%// Generate data
Z = peaks(25);
%// Create handles to access/modify data.
hSurf = surf(Z);
k = 0;
%// Set up name to create animated gif.
filename = 'AnimateSurf.gif';
%// Just a loop
while k < 10
%// IMPORTANT part. Update the Z data
set(hSurf,'ZData',k*Z);
%// Set limits so the graph looks nice.
zlim([-80 80])
drawnow
%// Capture frame to write to gif.
frame = getframe(1);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if k == 0;
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
pause(.15)
k = k+1;
end
And output:

How to do an animated plot in matlab

I was wondering if anyone knew how to do an animation plot of
x = (dataset of 1000 points)
y = (dataset of 1000 points)
plot(x,y)
big problem is these are datasets that i am trying to plot , or x,y coordinates as opposed to a function which I would know how to plot via an animation.
I tried to do frames in a for loop but it gave me dots and didn't join them in a line graph so I couldn't really watch the path being traced out.
code I used was
for i = 1:length(DATASET1)
pause(0.1)
plot(DATASET1(i),DATASET2(i))
draw on
end
If what you want is for the plot to "grow" point by point: the easiest way is to create an empty plot and then update its XData and YData properties at each iteration:
h = plot(NaN,NaN); %// initiallize plot. Get a handle to graphic object
axis([min(DATASET1) max(DATASET1) min(DATASET2) max(DATASET2)]); %// freeze axes
%// to their final size, to prevent Matlab from rescaling them dynamically
for ii = 1:length(DATASET1)
pause(0.01)
set(h, 'XData', DATASET1(1:ii), 'YData', DATASET2(1:ii));
drawnow %// you can probably remove this line, as pause already calls drawnow
end
Here's an example1 obtained with DATASET1 = 1:100; DATASET2 = sin((1:100)/6);
1 In case someone's interested, the figure is an animated gif which can be created by adding the following code (taken from here) within the loop, after the drawnow line:
frame = getframe(1);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if ii == 1;
imwrite(imind,cm,filename,'gif','Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
Looks like you were close. Not sure draw on is any command though.
See if the code here inspires you to solve your case -
%// Sample x and y values assumed for demo.
x = 1:1000;
y = x.^2;
%// Plot starts here
figure,hold on
%// Set x and y limits of the plot
xlim([min(x(:)) max(x(:))])
ylim([min(y(:)) max(y(:))])
%// Plot point by point
for k = 1:numel(x)
plot(x(k),y(k),'-') %// Choose your own marker here
%// MATLAB pauses for 0.001 sec before moving on to execue the next
%%// instruction and thus creating animation effect
pause(0.001);
end
Since R2014b, you can work with annimatedline object (doc and how-to) that is meant to handle animated graphs pretty well. Basically, the annimatedline object has a addpoints function that adds new points to the line without having to redefine the existing points, along with a clearpoints function that clears lines for more complex animations.
Here is an example:
h = animatedline;
axis([0,4*pi,-1,1])
x = linspace(0,4*pi,1000);
y = sin(x);
for k = 1:length(x)
addpoints(h,x(k),y(k));
drawnow
end