Matlab graphics do not update in successive runs - matlab

I have created a matlab figure plot and then plotted several rectangles.
for i=1:size(rect,2)/2
rectangle('Position',[rect(i)-1,rect(i+2*size(rect,2)),5,2])
end
Now i want to loop them thru a for-loop simulating the passage of time.
daspect([1,1,1])
for t=0:0.1:6.28
for i=1:size(rect,2)/2
rectangle('Position',[rect(i)-1-2*sint(t),rect(i+2*size(rect,2))-2*sin(t),5,2])
end
pause(0.1)
end
The trouble with the rectangle command is that for t=0, the figures are good but for t=0.1, the new figures overlap with figures of t=0 thus spoiling the graphics. What is the fix? I am not even using hold on.

What about using findobj to look for rectangles and delete them as new ones appear?
for t=0:0.1:6.28
for i=1:size(rect,2)/2
hRect = findobj('Type','rectangle')
delete(hRect)
rectangle('Position',[rect(i)-1-2*sint(t),rect(i+2*size(rect,2))-2*sin(t),5,2])
end
pause(0.1)
end

Something like this should work to clear the rectangle before plotting the next one
for t=0:0.1:6.28
delete(h)
for i=1:size(rect,2)/2
h=rectangle('Position',[rect(i)-1-2*sint(t),rect(i+2*size(rect,2))-2*sin(t),5,2])
end
pause(0.1)
end

Related

Plotting an ode solution when clicking on the axes

I am attempting to write some code that will allow me to click on the axes and the ode solution with the clicked point as the initial condition will be plotted. Here is what I have tried thus far:
function myui
clc
close all
xmin=2;
xmax=10;
ymin=-4;
ymax=4;
f=#(t,y) y^2-t
fig=figure;
ax=axes('Units','pixels',...
'XLim',[xmin,xmax],...
'YLim',[ymin,ymax],...
'ButtonDownFcn',#plotode)
function plotode(source,event)
initcond=get(ax,'CurrentPoint');
initcond=initcond(1,1:2)
[t,y]=ode45(f,[initcond(1),xmax],initcond(2));
plot(t,y)
hold on
[t,y]=ode45(f,[initcond(1),xmin],initcond(2));
plot(t,y)
axis([xmin xmax ymin ymax])
hold off
end
end
I have several questions.
I can only click one time. I'd like to click several times and draw several curves.
The curve can shoot to plus or minus infinity quite quickly, so I'd like to halt ode 45 if it leaves my axes window.
I'd appreciate it if someone could share some complete code that works as I could really learn quite a bit.
Thanks.
All,
I've added some steps to my code that performs the task I wished to see.
function myui
% clear command window and close all open figures
clc
close all
% define our function
f=#(t,y) y^2-t;
% axes boundaries
tmin=2;
tmax=10;
ymin=-4;
ymax=4;
% steps for quiver
tstep=20;
ystep=20;
% create a figure window
fig=figure;
% create axes with limits
ax=axes('Units','Normalized',...
'XLim',[tmin,tmax],...
'YLim',[ymin,ymax]);
% create direction field with quiver
[T,Y]=meshgrid(linspace(tmin,tmax,tstep),...
linspace(ymin,ymax,ystep));
S=Y.^2-T;
L=sqrt(1+S.^2);
quiver(T,Y,1./L,S./L,0.5,'r','ButtonDownFcn',#plotode)
axis tight
hold on
% set ButtonDownFcn on axes ax
set(ax,'ButtonDownFcn',#plotode);
% function plots initial conditions and solutions
function plotode(source,event)
warning('off','MATLAB:ode45:IntegrationTolNotMet');
initcond=get(ax,'CurrentPoint');
initcond=initcond(1,1:2);
[t,y]=ode45(f,[initcond(1),tmax],initcond(2));
plot(t,y,'b','linewidth',1)
[t,y]=ode45(f,[initcond(1),tmin],initcond(2));
plot(t,y,'b','linewidth',1)
plot(initcond(1),initcond(2),'ro')
set(ax,'XLim',[tmin,tmax],'YLim',[ymin,ymax],...
'ButtonDownFcn',#plotode);
end
end
It produces this image when I click on the axes with my mouse several times.
I'd still love to listen to some instruction and suggestions.
Thanks.

How to delete existing graph and plot a new graph?

In my program, I am doing a least squared optimization problem, i.e. \sum_{i} (y_{i}-y_{i}^{market})^2. At the same time, I want to plot the modeled y_{i} against the y_{i}^{market}. To program it which suit my needs, I define OutputFcn during my optimization and write the code as follow: (Suppose x represent the x-coord
figure()
hold on
plot(x,[y_{1},y_{2},...,y_{n}]);
plot(x,[y_{1}^{market},y_{2}^{market},...,y_{n}^{market}]);
When I run the program, I can draw a new calculated curves on the same plot. Unfortunately, the final plot is difficult to view it. In order to make it to be visible to read, I want to delete the curve (calculated values) obtained in the previous iteration and plot the new curve (calculated values) in the new iteration on the existing plot. What should I do to the current code to fulfill my needs?
Something like:
hold on
for iterations
clf
% PLOT STUFF
drawnow
pause(0.1)
end
clf clears the figure
drawnow forces drawing on screen
pause stops execution for a bit so you have time to see it.

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.

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

How to create a new figure in MATLAB?

Usually when I plot in MATLAB, it always draws on the same figure. How do I make it draw in a new figure?
I know it is pretty elementary, but I'm not finding it using Google Search.
figure;
plot(something);
or
figure(2);
plot(something);
...
figure(3);
plot(something else);
...
etc.
While doing "figure(1), figure(2),..." will solve the problem in most cases, it will not solve them in all cases. Suppose you have a bunch of MATLAB figures on your desktop and how many you have open varies from time to time before you run your code. Using the answers provided, you will overwrite these figures, which you may not want. The easy workaround is to just use the command "figure" before you plot.
Example: you have five figures on your desktop from a previous script you ran and you use
figure(1);
plot(...)
figure(2);
plot(...)
You just plotted over the figures on your desktop. However the code
figure;
plot(...)
figure;
plot(...)
just created figures 6 and 7 with your desired plots and left your previous plots 1-5 alone.
The other thing to be careful about, is to use the clf (clear figure) command when you are starting a fresh plot. Otherwise you may be plotting on a pre-existing figure (not possible with the figure command by itself, but if you do figure(2) there may already be a figure #2), with more than one axis, or an axis that is placed kinda funny. Use clf to ensure that you're starting from scratch:
figure(N);
clf;
plot(something);
...
As has already been said: figure will create a new figure for your next plots. While calling figure you can also configure it. Example:
figHandle = figure('Name', 'Name of Figure', 'OuterPosition',[1, 1, scrsz(3), scrsz(4)]);
The example sets the name for the window and the outer size of it in relation to the used screen.
Here figHandle is the handle to the resulting figure and can be used later to change appearance and content. Examples:
Dot notation:
figHandle.PaperOrientation = 'portrait';
figHandle.PaperUnits = 'centimeters';
Old Style:
set(figHandle, 'PaperOrientation', 'portrait', 'PaperUnits', 'centimeters');
Using the handle with dot notation or set, options for printing are configured here.
By keeping the handles for the figures with distinc names you can interact with multiple active figures. To set a existing figure as your active, call figure(figHandle). New plots will go there now.
Another common option is when you do want multiple plots in a single window
f = figure;
hold on
plot(x1,y1)
plot(x2,y2)
...
plots multiple data sets on the same (new) figure.
As simple as this-
figure, plot(yourfigure);