MATLAB - display figure only when everything has been plotted - matlab

I'm trying to plot a 2d finite element solution and am plotting triangle-by-triangle like so:
for i=1:K
figure(1)
fill3(x,y,z,c)
hold on
end
The problem with this is that when I run the code, it literally draws them all in real time so I can see each triangle being drawn. What I want it to just have the finished figure pop up once it's all done.
My friend has coded the same thing except she's not having this issue at all and we can't find any differences in the code. My computer is very fast so it's not an issue of lag. I'm thinking maybe there's a setting in MATLAB that I'm missing?
Edit: I found the problem. Apparently, putting 'figure(1)' inside the loop makes a huge difference. I timed it with 'tic' and 'toc' and it took 54 seconds with the 'figure(1)' label inside the loop and 2 seconds when it was moved just before the loop. Go figure...

When you start the figure, set the visible property to 'off'; when you are done plotting, set the visibility to 'on'.
h = figure('visible','off');
hold on;
for i=1:K
fill3(x,y,z,c);
end
hold off;
set(h,'visible','on');
Also, I'm not entirely sure how the event queue works in MATLAB, but I'm fairly sure the fact you have a fast computer is effecting this. You can simulate what's happening with your computer by using drawnow on your friends slower comp within the for-loop.

Related

Drawnow on Matlab: It store the figure or store the variable?

May you please help me on a question on DRAWNOW in Matlab?
When we using drawnow in Matlab, what happens inside?
It stores the figure of the previous-graph, then plot the next-part-of-graph on the same figure?
OR it forgets the whole previous-graph and plot the actual-new-graph (with both previous and next-part)?
The both methods show the same effect: a dynamic graph. But I want to know exactly what happens inside.
Thank you!
drawnow makes sure that MATLAB stops doing whatever its doing and draws in the screen.
If you do
hold on
for ii=1:1000
plot(ii,rand(1)); % assume complicated maths here
end
MATLAB will run the code and send the plot calls to the graphics engine. However, MATLAB is too busy running the loop to be drawing, as the code has priority over the plot.
If you do
hold on
for ii=1:1000
plot(ii,rand(1));
drawnow; % Take a break, draw everything that you must before continuing
end
Then, as the comment says, you temporarily stop the execution of the code, to draw everything in the graphics pipeline, and then continue executing the code.
drawnow has no influence in the fact that the figure is stored or not, that is the job of hold on.
If you are worried about redrawing the whole thing, then make sure you have a look at set and get methods for graphics. With them you can get the xdata, modify it, and set it again, by ensuring that the graphics engine does not redraw/recompute anything else.
Documentation for the hold function:
https://uk.mathworks.com/help/matlab/ref/hold.html

MATLAB: plot in a loop

I've tried to do plot inside of a loop and it prints only the last plot.
How can i fix it?
I've tried to use hold on and drawnow after the plot definition but it didn't work.
This is my code:
for t=1:5
alive = Game(World , Generations, speed);
plot(hplot2,1:Generations,alive);
end
hold on should work. Try this:
figure
hplot2=gca;
hold on
for t=1:5
alive = rand(1,Generations);
plot(hplot2,1:Generations,alive);
end
Sticking in a "figure" has always worked for me.
for t=1:5
alive = Game(World , Generations, speed);
figure;
plot(hplot2,1:Generations,alive);
end
Since you are already passing the axes handle to plot, you only need to put something like pause(0.1) inside the loop, and your original source will work.
you can also use figure(t) to have 5 different figures.
If the function Game(World , Generations, speed) is a deterministic function - it gives the same output for every t. Therefore, every plot commands has exactly the same output and you cannot distinguish the first from the last plot.
Try plot a random series at each iteration (as in answer of shoelzer) and see if you see all 5 plots.
Additionally, you might want to use hold all instead of hold on: this way each plot will get a different color from the colormap.

Plot multiple figures in background

I have a MATLAB code that plots multiple figures at the same time. The general trick to achieve the same is to call figure(figHandle) and then make a call to plot, for e.g.
figure(h1);
plot(...args...);
figure(h2);
plot(...args...);
However, I want to do this plotting without bringing figures into foreground everytime I make a call to figure(figHandle). All I want to do is to plot multiple figures simultaneously without bringing them into visibility and export them to an excel sheet (I have figured out exporting to excel sheet part) in the end.
The problem is there are too many figures (around 100) and I have to manually close them down. All I want in the end is an excel sheet with figures exported.
Thanks.
If the problem is to close all the figures you can just use the command close all.
I agree with the solution of mola (+1). However, if you did for some reason wish to keep the figures available after exporting to excel, but don't want them visible on screen, just set the visible property of the figure to off when creating it:
fig1 = figure('visible', 'off')
And if you suddenly decide you need to see it:
set(fig1, 'visible', 'on')
EDIT: It just occurred to me, that if you don't care about ever seeing the figures in matlab, then you should definitely be setting the visible property of the figure to off when you create it. This should significantly speed up the runtime of your code. For example:
x = (1:100)';
tic
for i = 1:1:10
fig1 = figure('visible', 'off');
plot(x);
end
close all
toc
takes 0.27 seconds to run on my machine, but if I switch 'off' to 'on', the runtime increases to 0.65 seconds.
Assign figure handles like
fig1 = figure
run
close figure1
to close figure1 when you’re through with it. Also, if you want to plot multiple things in one figure by tiling, use the subplot function.
When I run Matlab from terminal, and I want to generate a bunch of plots to be saved in an html file, I run this function I wrote, passing the script of interest as an argument, and simply set it and forget it:
function directoryOutput = cliPub(scriptName)
clc;
close all;
fprintf('Publishing...\n\n');
directoryOutput = publish(fullfile(pwd, scriptName), 'figureSnapMethod', 'getframe', 'useNewFigure', false);
close all;

Close/pause process in Matlab

I have a code with a lot of plots. The problem (excuse my ignorance because I don't know if it's possible) is, for example, when I execute since the beginning, I directly see the last plot, not one after the other. So, for example, I've tried this but it doesn't work at all:
pause(2); %After two seconds it starts and open the plot but I directly see the last plot, not this
plot (x, y);
title ('Average values')
close; % The command close it works but only if I press 'evaluate function'
pause(2);
plot (out1,out2);
close;
Also, I've tried with the keyboard command to try if it's possible to close the plot with one key and then, open the other with another key but I couldn't do it.
If someone knows how can I do it I will be so I'll be so grateful,
Matlab does plotting and the calculation typically in the same process. So typically you will not get anything displayed till there is some spare time for plotting in your program.
To force matlab to redraw the windows you can use the drawnow command. But it only draws exactly at the moment - so if your figure window would be hidden or behind some other window, the redrawing when it comes to foreground will not happen till the next time.
In your case you also close the plot before the pause (where it could be displayed). So if you'd exchange the two commands you should see it. The obvious drawback of the pause is - it halts your program for the time.
from my experience I would suggest you rather save the plots as graphic files and use some external program to view them.
Also I find the popping up new windows annoying and interrupting my workflow - so I would reuse the graphic window, by just clearing it with clf.
I may misunderstand what you are trying to do, but when i try to create what you describe it just works for me as expected. Here is my example:
Note that you will want to close any open figure windows to ensure that it pops up rather than letting it stay in the background.
pause(2); % Wait 2 seconds before starting
plot(1:10); % Plot an upward line
title('up'); % Give it a title
pause(2); % Wait 2 seconds before showing the next plot
plot(10:-1:1); % Plot an downward line
title('down'); % Give it a title
Depending on how you want to use them, saving the plots may be a nicer solution.

Why won't this axes object display correctly in MATLAB?

I am writing two small psychoacoustic testing applications in MATLAB. The first one works without problems but the second one doesn't, and I just can't figure out why.
Here is the problem: the axes object is created, but it is empty.
failed_axis http://dl.getdropbox.com/u/98854/help.png
Here is the code that creates this figure and axes:
hFig = figure('dockcontrols','off','menubar','none', ...
'name','choose the better sounding file', ...
'numbertitle','off','position',[0,0,700,500], ...
'resize','off','toolbar','none','units','normalized', ...
'color',[.8,.8,.8]);
progress_idc = axes('position',[.1,.8,.8,.05],'box','on','parent',hFig,...
'xlim',[-.03,1.03],'xtickmode','manual','xtick',[], ...
'xticklabelmode','manual','xticklabel',[], ...
'ylim',[-1,1],'ytickmode','manual','ytick',[], ...
'yticklabelmode','manual','yticklabel',[], ...
'nextplot','add');
And here is the code that plots in this axes (the function is called regularly by a timer):
function replot(varargin) % this is a nested function
cla;
% plot start_indicator
plot([x_start,x_start],[-.7,.7],'k','linewidth',2);
fill([x_start,x_start-.02,x_start-.02],[0,-.7,.7],[0,0,0]);
% plot stop_indicator
plot([x_stop,x_stop],[-.7,.7],'k','linewidth',2);
fill([x_stop,x_stop+.02,x_stop+.02],[0,-.7,.7],[0,0,0]);
% plot play_position
plot([x_play,x_play],[-1,1],'r');
drawnow;
end
This is what it looks like if it works:
proper_axis http://dl.getdropbox.com/u/98854/help2.png
Do you have any idea what is going wrong here?
I ran the code you included above and got the correct output.
If I had to take a wild guess as to what the problem is, I'd guess that you may be creating other axes in your application that you are not listing above, or that you may have other axes not related to the application open at the time the application is running. When you plot your objects in the function replot, you are by default plotting them to the currently active axes. If you have multiple axes open, the plotting may therefore be going on in the wrong set of axes.
One suggestion I would make is to explicitly specify what the parent axes object should be in your calls to PLOT and FILL. If you add the arguments ...,'Parent',progress_idc); to your plotting calls, it will ensure that the correct axes is always used. I make a habit of always specifying the parent axes object instead of assuming that the currently active axes will always be the one I need it to be.
I finally found the (dumb) answer. The title accidentally had the same position as the plot axis. Due to some rendering-details of Matlab, it obscures the whole axis except for the rightmost and bottommost line of pixels, which makes the axis look "empty".
Oh, what a dumb error.