Matlab change a single point in a plot without replotting - matlab

So I have a plot of N points in the 2D plane (N can be very large). I am writing a script that is to show the workings of an algorithm. So I have for loops. At each step in the for loop I'd like to change the color of the current point (actually probably make a stem plot with just this point).
However, at the end of the step I'd like to remove the coloring of the current point so that I can color the next one. Currently I have to redraw the whole plot (incl. the 2D points). I'm not sure whether Matlab detects such things in the plotting commands but is there a way to do this without redrawing the whole plot?
For example:
plot(x,y, '*');
for j = 1:N-1
for i = j:N
hold on;
%Do stuff
plot(x,y, '*');
hold on;
stem(x(1), y(1), 'g*');
end
end

A quick example:
%# plot some data
x = 1:100;
y = cumsum(rand(size(x))-0.5);
plot(x,y,'*-')
%# animate by going through each point
hold on
h = stem(x(1),y(1),'g');
hold off
for i=1:numel(x)
%# update the stem x/y data
set(h, 'XData',x(i), 'YData',y(i));
%# slow down a bit, drawnow was too fast!
pause(.1)
end

Take a look at the documentation of handle graphics objects.
I'd recommend plotting the whole set of points as one object. Then, for each iteration, plot the point of interest. Save a handle to it (as in, h = plot(...);). When you're ready for the next iteration, delete the object using that handle (delete(h)), and create the next one in the same manner.
%# outside the for loop (do this once)
plot(x,y,'*');
for...
h = stem(x(i),y(i),'g*');
...
%# next iteration... i has been incremented
delete(h);
h = stem(x(i),y(i),'g*');
end

Related

Animate through multiple 2D Matlab plots

I have multiple 2D line plots in Matlab (they represent some wave moving through space). Each plot represents the wave at some time t. I want to animate through these plots (i.e. show the first plot for a fraction of a second, then show the next one, and the next, etc. I want to loop back to the beginning once it reaches the end time) to show the time evolution of the system. surf and mesh don't really do what I want since it is too difficult to see the changes with the number of time steps I have. Is there a way to do this in Matlab?
I assume with "2d-line" you mean a 2d-plot. This is done by the plot-function, so there is no need of surf or mesh. Sorry, when I got you wrong.
The following code does what I think you asked for:
% Generate some propagating wave
n = 20;
t = linspace(0,10,100);
x = cell(1,n);
for i = 1:n
x{i} = (1-abs(i/n-0.4))*sin(t+i*0.2);
end
% Create frames
figure;
for i = 1:length(x)
clf;
plot(t,x{i});
ylim([-1,1]);
myFrames(i) = getframe; %#ok<SAGROW>
end
% Show movie
figure;
movie(myFrames,2,2); % frames, repetitions, frames per second

MATLAB's drawnow doesn't flush

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.

Matlab continue graph for second loop

%free fall of a ball
clc
clear all
close all
v0=5; % initial velocity up
g=9.8; %free fall acceleration
v1=(0.7/0.9)*v0
% time of fly
tup=v0/9;
nsteps=10; %number of frames
dt=tup/nsteps; %time step
Hmax=v0*tup+(-g)*tup*tup/2; % maximum altitude
altitude(1:nsteps+1)=0; %define array for position Y
time=0:dt:tup;% define time array
%initilaise plot
figure(1)
axis([0,2*tup,0,2*Hmax]);
hold on
% loop
for i=1:nsteps
altitude(i)=v0*time(i)+(-g)*time(i)*time(i);
plot(time(i),altitude(i), 'ro')
grid on;
M(i)=getframe;
end
%loop bouncing
for i=1:nsteps
altitude(i)=v1*time(i)+(-g)*time(i)*time(i);
plot(time(i),altitude(i), 'ro')
grid on;
M(i)=getframe;
end
%make movie
movie(M);
movie2avi(M, 'C:\Users\Mehmet\Desktop\avi\mm','compression','none');
%extra plots
figure(2)
plot(time(1:nsteps),altitude(1:nsteps))
figure(3)
plot(time(1:nsteps),altitude(1:nsteps),'ro')
We have this ball bouncing simulation. What we want to do is, to continue loop 2 after loop 1 in graph.So, it will be continious bouncing simulation.2 bouncings are shown from 1:10 steps but we want second loop to be shown after 10 steps.
There are a couple of approaches, depending upon what effect you're going for. The simplest is to simply add hold on as a separate command after each of your plot commands. This will keep accumulating new lines/dots without erasing the old ones. To stop this effect, add a hold off command. The next plot command will then erase everything and plot on a clean graph.
Alternatively, if you only want to show a fixed number of the previous steps (and not all of them, as the hold on will do), you'll have to explicitly hold onto the previous values. Something like this:
% loop
max_history = 10; %plot this many symbols
for i=1:nsteps
altitude(i)=v0*time(i)+(-g)*time(i)*time(i);
%get the historical and current data points to plot
start_ind = i-max_history+1; %here's the oldest point that you'd like
start_ind = max([start_ind, 1]) %but you can't plot negative indices
inds = [start_ind:i]; %here are the ones to plot
%update the plot
plot(time(inds),altitude(inds), 'ro');
grid on;
%you might need a "drawnow" here
M(i)=getframe;
end
Copy this same idea into your other for loops and you should be good-to-go!

plot hold for plot3 matlab

There is a similar question, to which the answer was given. My question is the same as this one, except, I have 2 loops instead of one as showed there. Still, the solution does't seem to work for me.
The question : How to hold a plot when using plot3 in matlab?
Here, there is a single loop ad the solution seems to work fine. The following is my code :
figure(1)
for i = 1:n
for j = 1:m
if(condition)
%some calculations to get X
x = X(1,:);
y = X(2,:);
z = X(3,:);
plot3(x,y,z,'.');
view(3);
hold on;
end
end
hold on;
end
Here, after all iterations of the inner loop using 'j', am getting a proper plot, but once it goes to the outer loop, the plot refreshes and starts again. How can I maintain the plot3 for both the loops? I have used hold on again in the outer loop, but it still doesn't seem to work. Can anyone tell me how I can maintain the plot for 2 loops.? Thanks in advance.
I think that your code should work as is. However, a few changes I would make, which should help whatever problem that you are having:
hold on only needs to be called once.
view(3) also only needs to be called once (actually is not needed at all to get the data plotted, just helps with the visualization).
When I'm performing complex plotting, I usually need to specify the axis to plot on explicitly. Otherwise the plot goes to the "current" axis, which can be changed by some operations. (Depends what you are doing in your calculations.)
A common problem when it looks like data is not being added to a plot is axis scaling. You can use axis tight for a decent first guess at scaling the axis limits.
Putting this together, try this, and see what happens:
%Set up figure to catch plots
figure(1);
hAxis = gca; %This will create an axis in the figure, and return its handle
hold on; %You can also use hold(hAxis,'on') if you are really paranoid about which axis is catching your commands
%Perform plots
for i = 1:n
for j = 1:m
if (condition)
%some calculations to get X
x = X(1,:);
y = X(2,:);
z = X(3,:);
plot3(hAxis,x,y,z,'.');
end
end
end
%Adjust view etc (experiment here after the data is plotted)
view(3)
axis tight

two simultaneous plots in matlab

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