I am doing something like this:
a = [1:100];
for i=1:100,
plot([1:i], a(1:i));
end
My issue is that the plot is not shown until the loop is finished.
How can I show/update the plot in every iteration?
Use DRAWNOW
a = [1:100];
for i=1:100,
plot([1:i], a(1:i));
drawnow
end
Alternatively, you may want to have a look at ANYMATE from the file exchange.
Another way to do this if you just want to visualise it without saving the animation, is to use refreshdata instead of plot for subsequent plots. You will still need to call drawnow for it to update on-screen.
either use
set(fig_handle,'XData',new_xdata_array)
set(fig_handle,'YData',new_ydata_array)
refreshdata
drawnow
or use
set(fig_handle,'XDataSource',xdata_array)
set(fig_handle,'YDataSource',ydata_array)
%call this whenever xdata_array and ydata_array are assigned new values to see it updated in the plot
refreshdata
drawnow
for your example, this might look like:
a=[1:100];
figure;
h=plot(1,a(1));
for i=2:100
set(h,'XData',[1:i])
set(h,'YData',a(1:i))
refreshdata
drawnow
end
It's not all that useful for simple line plots (for which plot(); drawnow; is simpler and faster), but when you need to create more complicated figures involving multiple plot types, this can be useful.
From the documentation for comet.m
t = 0:.01:2*pi;
x = cos(2*t).*(cos(t).^2);
y = sin(2*t).*(sin(t).^2);
comet(x,y);
Matlab allows you to sort-of automate a loop statement for variables
x = 0.0:0.1:2*pi
plot(x,cos(x));
is an example......
A lot of times you don't really need to plot 'in' a loop
Related
I am doing something like this:
a = [1:100];
for i=1:100,
plot([1:i], a(1:i));
end
My issue is that the plot is not shown until the loop is finished.
How can I show/update the plot in every iteration?
Use DRAWNOW
a = [1:100];
for i=1:100,
plot([1:i], a(1:i));
drawnow
end
Alternatively, you may want to have a look at ANYMATE from the file exchange.
Another way to do this if you just want to visualise it without saving the animation, is to use refreshdata instead of plot for subsequent plots. You will still need to call drawnow for it to update on-screen.
either use
set(fig_handle,'XData',new_xdata_array)
set(fig_handle,'YData',new_ydata_array)
refreshdata
drawnow
or use
set(fig_handle,'XDataSource',xdata_array)
set(fig_handle,'YDataSource',ydata_array)
%call this whenever xdata_array and ydata_array are assigned new values to see it updated in the plot
refreshdata
drawnow
for your example, this might look like:
a=[1:100];
figure;
h=plot(1,a(1));
for i=2:100
set(h,'XData',[1:i])
set(h,'YData',a(1:i))
refreshdata
drawnow
end
It's not all that useful for simple line plots (for which plot(); drawnow; is simpler and faster), but when you need to create more complicated figures involving multiple plot types, this can be useful.
From the documentation for comet.m
t = 0:.01:2*pi;
x = cos(2*t).*(cos(t).^2);
y = sin(2*t).*(sin(t).^2);
comet(x,y);
Matlab allows you to sort-of automate a loop statement for variables
x = 0.0:0.1:2*pi
plot(x,cos(x));
is an example......
A lot of times you don't really need to plot 'in' a loop
I am doing something like this:
a = [1:100];
for i=1:100,
plot([1:i], a(1:i));
end
My issue is that the plot is not shown until the loop is finished.
How can I show/update the plot in every iteration?
Use DRAWNOW
a = [1:100];
for i=1:100,
plot([1:i], a(1:i));
drawnow
end
Alternatively, you may want to have a look at ANYMATE from the file exchange.
Another way to do this if you just want to visualise it without saving the animation, is to use refreshdata instead of plot for subsequent plots. You will still need to call drawnow for it to update on-screen.
either use
set(fig_handle,'XData',new_xdata_array)
set(fig_handle,'YData',new_ydata_array)
refreshdata
drawnow
or use
set(fig_handle,'XDataSource',xdata_array)
set(fig_handle,'YDataSource',ydata_array)
%call this whenever xdata_array and ydata_array are assigned new values to see it updated in the plot
refreshdata
drawnow
for your example, this might look like:
a=[1:100];
figure;
h=plot(1,a(1));
for i=2:100
set(h,'XData',[1:i])
set(h,'YData',a(1:i))
refreshdata
drawnow
end
It's not all that useful for simple line plots (for which plot(); drawnow; is simpler and faster), but when you need to create more complicated figures involving multiple plot types, this can be useful.
From the documentation for comet.m
t = 0:.01:2*pi;
x = cos(2*t).*(cos(t).^2);
y = sin(2*t).*(sin(t).^2);
comet(x,y);
Matlab allows you to sort-of automate a loop statement for variables
x = 0.0:0.1:2*pi
plot(x,cos(x));
is an example......
A lot of times you don't really need to plot 'in' a loop
Is there any reason that MATLAB's drawnow wouldn't flush?
This is my code:
j=1;
for k = 1:length(P)
for i = 1:n
plot(P(k,j),P(k,j+1),'.');
j = j+2;
end
axis equal
axis([-L L -L L]);
j=1;
drawnow
end
(rungekutta4 is my own function I wrote, and it works OK, so the problem isn't there.)
The particles just stay drawn on the plot and don't get overwritten every time the loop executes.
How could I fix this problem?
The proper and efficient way to do this is with handle graphics. You should also vectorize your plot commands.
% Example data to make runnable
L = 1;
n = 10; % Number of points
P = 2*rand(1e2,n+1)-1;
% Initialize plot, first iteration
h = plot(P(1,1:n),P(1,2:n+1),'.'); % Plot first set of points and return handle
axis equal;
axis([-L L -L L]);
hold on; % Ensure axis properties are fixed
drawnow;
% Animate
for k = 2:size(P,1) % size is safer in this case
% Use handle to update the positions of the previously plotted points
set(h,{'XData','YData'},{P(k,1:n),P(k,2:n+1)});
drawnow;
pause(0.1); % Slow down animation a bit to make visible
end
Calling clf and/or plot on each iteration of an animation causes many things already in memory to be unnecessarily deleted and reallocated, resulting much slower code. It may also result in flickering in some cases.
See also this very similar question and answer.
When you want to animate something, you want to, of course, force draw. Thats what the command drawnow is there for. But there are other things to consider!
One of them is that you need to make sure that everything is drawn in each frame. For that, use the hold on function just before you start drawing (plot).
However, you also need to make sure that you clear the image before drawing, else the plots will stack forever. Use the clf "clear figurecommand before the previously mentionedhold on` and that will do the job.
remember that if the animation is too fast you can always add a pause(0.2) line after drawnow to slow it.
I used the plot command to plot a figure and then changed lots of its properties using set command. I also store the handle of the plot (say h1).
What I need is to use the handle to plot the same figure again later in my code. I checked the plot command and did not find any version that accepts handle. I also thought of getting the Xdata and Ydata and use them to re-plot the same figure.
What is the simplest solution?
Edit 1: A working sample code based on copyobj that PeterM suggested.
hf(1) = figure(1);
plot(peaks);
hf(2) = figure(2);
plot(membrane);
hf(3) = figure(3);
ha(1) = subplot(1,2,1);
ha(2) = subplot(1,2,2);
for i = 1:2
hc = get(hf(i),'children');
hgc = get(hc, 'children');
copyobj(hgc,ha(i));
end
Edit 2: I also found this function that can copy figures (including legend) into a subplot.
I have run into this situation before. Depending on what you are trying to do the function copyobj may be appropriate. This function lets you take the contents of one axes and copy it to a new figure.
Improving #PeterM nice answer, one easier way would be:
fig2H=copy(gcf) % or change gcf to your figure handle
But it depends on what you want, if you want only the axes, or the whole figureā¦ (btw, it doesn't seem to copy the legend handle).
You can use saveas to save the figure in a file, and the open to load the exact same figure from this file.
This would be the laziest way to accomplish what you want.
% Sample plot
f1 = figure(1);
plot(0:0.1:2*pi, sin(0:0.1:2*pi));
f2 = figure(2);
% The code you need
saveas(f1, 'temp.fig')
f2 = hgload('temp.fig')
delete('temp.fig')
I have used the function figs2subplots (given in Edit2 in the original question) - it does the work and is very easy to use.
I want to plot two simultaneous plots in two different positions in Matlab, looped animations and both are different animations, one with hold on and another with hold off.
Also, one is 2D and one is 3D
I am doing something like this:
for i=1:some_number
axes('position',...)
plot(...);hold on;
axes('position',...)
clf
plot3(...) (or fill3 but has to do with 3d rendering)
view(...)
set(gca, 'cameraview',...)
set(gca,'projection',...)
mov(i)=getframe(gcf)
end
Q1. Do the set properties effect first axes? if so, how to avoid that?
Q2. In my plot hold on did not work. Both were instantenous. like using hold off. How do I make it work?
Q3. I hope the mov records both axes.
P.S. I hope clf is not a problem. I must use clf or if there are equivalents more suitable in my case do suggest me.
You need to store the return from the axes function and operate specifically on a given axes with subsequent function calls, rather than just the current axes.
% Create axes outside the loop
ax1 = axes('position',...);
ax2 = axes('position',...);
hold(ax1, 'on');
for i=1:some_number
plot(ax1, ...);
cla(ax2); % use cla to clear specific axes inside the loop
plot3(ax2, ...) (or fill3 but has to do with 3d rendering)
view(ax2, ...)
set(ax2, 'cameraview',...)
set(ax2,'projection',...)
mov(i)=getframe(gcf)
end
Here is a snippet from a piece of my code which plots orbits of three celestial bodies which I think will help you:
for i = 1:j, %j is an arbitrary number input by the user
plot(x, y, '*')
plot(x2, y2, 'r')
plot(xa, ya, '+')
grid on
drawnow %drawnow immediately plots the point(s)
hold on %hold on keeps the current plot for future plot additions
%dostuff to x,y,x2,y2,xa,ya
end
The two main functions you want are the drawnow and hold on.
Just to note: x,y,x2,y2,xa, and ya change with each iteration of the loop, I have just omitted that code.
EDIT: I believe the drawnow function will solve your problem with hold on.
I think this may solve your problem.
for i=1:some_number
axes('position',...)
plot(...);
drawnow %also note that you must not put the ; at the end
hold on %see above comment
axes('position',...)
clf
plot3(...) (or fill3 but has to do with 3d rendering)
view(...)
set(gca, 'cameraview',...)
set(gca,'projection',...)
mov(i)=getframe(gcf)
end