How to force drawnow Matlab GUI to draw in new window? - matlab

I have used drawnow to draw the characters of the mnist dataset.. which outputs the following output
when i created GUI with matlab and calling drawnow to display images after loading it draws the figure on the open window giving the following output
my question is how to force it to draw in new window ?

drawnow only asks Matlab to flush the event queue and update figure windows; it doesn't determine how and where things are plotted. It's hard to tell since you don't include any code, but in your case it looks like you just plot the character images and the GUI elements into the same figure.
You can control which figure window a graphics operation refers to by setting the "current figure", whose handle is always contained in the variable gcf (graphics: current figure).
You generate a new figure and make it current by calling
figure
If you want to later make this figure current again, you need to save its handle:
fa = figure;
You then make a figure with a given handle current again by
figure(fa)
Some rough sketch of a possible program:
% generate figure windows
fa = figure;
fb = figure;
% plot something in figure a and make the screen update
figure(fa)
plot(...)
drawnow
% put a UI element into figure b and make the screen update
figure(fb)
uicontrol(...)
drawnow

Related

Set figure to not be target for next plot

I'm working on a custom progress monitor with some graphs. I've noticed that Matlab's waitbar creates a figure with some special properties so that if you do
plot(rand(100,1));
wb = waitbar(0);
plot(rand(100,1));
the second plot ends up replacing the first plot and not in wb. Is there a property I can set so that when I create my progress monitor and then plot something afterwards, the graph doesn't end up in my figure?
To be clear, I'm trying to have
plot(rand(100,1));
temp = MyProgressBar();
plot(rand(100,1));
create a figure for the first plot, create a different figure in the second line, then plot a new graph in the third line.
To protect your progress bar figure against subsequent plotting operations, I would set the 'HandleVisibility' property of its axes to 'off'. That should prevent it ever becoming the current axes, thus keeping subsequent plotting commands from modifying or adding to it. It's a good practice for stand-alone figures/GUIs in general that you turn off the handle visibility of all objects (figure, uicontrols, etc.) in this way to insulate them against being modified by outside code. This is almost certainly what is done in the code for waitbar.
As an additional aside, it's good practice to target your plots to a given axes by passing the axes handle as the first argument. You also have to make sure that, if you want new plots to be added to existing plots, you use things like the hold command first. Here's how I'd rework your example, assuming you want the two plots to appear on the same axes:
plot(rand(100,1)); % Creates new figure and axes
hAxes = gca; % Get the axes handle
hold on; % Allow subsequent plots to be added
temp = MyProgressBar();
plot(hAxes, rand(100,1)); % Will be added to the first plot axes

Updating chart in a GUI with Timer creates a new figure & axes

I am trying to make a program that displays live chart data from a broker once in a period. The period could be for example 5 seconds or 15 minutes.
I have made a GUI and a Timer. When the program starts, the first plot goes to the axes in the GUI. However, all the updated plots (from the timer) come to a new figure (only one), but not into the figure in the GUI.
Attached is some code:
This is in the openingFcn of the GUI .m-file
handles.timer = timer(...
'ExecutionMode', 'fixedRate', ... % Run timer repeatedly
'Period', 5, ... % Initial period is 5 sec.
'TimerFcn', {#updateChart,hObject}); % Specify callback
guidata(hObject,handles)
axes(handles.axes1);
candle(highBid, lowBid, closeBid, openBid);
start(handles.timer);
And the function updateChart:
function updateChart(hObject,eventdata,hfigure)
% Get new data, one candle at a time
...
% How many times the chart has already updated
handles = guidata(hfigure);
k = handles.timer.TasksExecuted;
...
% Draw (update) the chart
hold on;
axes(handles.axes1);
candle(highBid, lowBid, closeBid, openBid); % this will be plotted in a new figure !
Any suggestions on how to update the chart at the GUI window?
I found the way to solve it. Indeed the same thing happens with any kind of high level plotting function. I had to reproduce your problem with the plot function and the behaviour was as you described.
Short answer:
you have to set the HandleVisibility of the figure to on (instead of the default setting callback). If you are working with GUIDE you have to set that directly in the figure property inspector from GUIDE (for some obscure reason it does not work if this is set later in the initialisation code):
This settings will let the timer callback have visibility of the figure children object so the plot command will not decide to create a new set of axes & figure when faced with invisible ones.
Note 1:
The plot was always refreshed in the right axes when the plot command was specified with the right target handle. For graphic functions which support passing the target axes in parameter, the syntax :
% infallible syntax (when allowed)
plot( data2plot , 'Parent',targetAxesHandle)
is always preferable to the one you were using (setting an axes active then plotting in the current active axes)
% this syntax may fail to plot in the right "axes" somtimes, as you observed
axes(targetAxesHandle);
plot( data2plot )
Now reading the documentation for your specific plotting function candle, I did not find clues that you can pass an axes handle to it, so for this type of function, you have to resort to the solution given on top of this post. However, if you ever give some feedback to the writers of the toolbox, I would strongly suggest to tell them about this important missing feature.
Note 2:
You do not have to call hold on before each plot. If you know you will always "add" to the plot, you can set it once and for all in the initialisation code:
set(handles.axes1,'Nextplot','add') % set "Hold on" permanently for "axes1"
And if you ever want to remove the locked hold, just set :
set(handles.axes1,'Nextplot','replace') % set "Hold off" permanently for "axes1"

Matlab openfig to existing figure

When in Matlab I use openfig(filename); to open a saved figure, it always opens a new window. All the 'reuse' argument does is not load the file when it appears to already be open. However, I wish to open the file into a given figure, and just overwrite its contents. Is there a way to pass a figure handle to openfig, or is there another function that would accomplish this?
So in code, what I would like to do is something along the following lines:
f = figure;
openfig(filename, 'Figure',f);
and then the figure would be displayed in figure f rather than having opened a second figure window.
I think you can arrange something close to what you want with the copyobj function. Here is a try with a docked figure:
% --- Create sample figure
h = figure;
ezplot('sin(x)');
set(gcf, 'Windowstyle', 'docked');
pause
% --- Replace the axes
clf
g = openfig('test.fig', 'invisible');
copyobj(get(g, 'CurrentAxes'), h);
delete(g);
Which gives me a smooth replacement of the axes, without flickering of the figure.
However, I don't know how this would behave with a fullscreen figure, it surely depends on the method you choose. Check also the doc of copyobj in detail, it's not copying everything so you may want to use the legacy option.

Redraw a figure saved in 2013b in 2014b

As MATLAB has changed its figure engine in R2014b I decided to rerun some of my code for getting better looking figures out of them. Unfortunately, the last one I have is a code that takes ages to run, and I would like to highly avoid to rerun the code for a nicer figure.
I saved the result in a .fig file in R2013b. However, if I open it in R2014b, it still has the old format.
Is it possible to redraw the figure using the MATLAB R2014b plotting engine? If it is, how could I do it?
NOTE: Literally, the figure is opened and drawn with the new engine, however, it retains its old format. While a new figure with a title() command would plot a nice big, bold title, if a redraw this figure using "drawnow" or I generate code for it, the format remains the same.
Example: This figure was created in 2013b, and redrawn in 2014b. You can see that the title does not plot in the same format as a title('whatever') would plot in the new graphic handles. It looks like that a '.fig' saves and sets the default values for the version it has been generated. Thus plot colors, titles, labels etc will look like the old graphic handles when redrawn.
This can be tested with the following code. Note that this is an overly simplified problem, the question is not explicitly about titles or labels, but all graphic stuff in general.
rng(1)
figure()
x = 1:50;
y = rand(1, 50);
plot(x,y)
title('this NICE Title')
xlabel('labels!')
ylabel('some other labels','Interpreter','Latex')
If this code is run in 2013b and 2014b, saved as fig in both and then opened as fig in both, the next 2 figures appear:
The 2013b fig file: http://s000.tinyupload.com/index.php?file_id=02053933004513599550
There is a roundabout way for doing this -- just using hgopen for loading the figure and then extracting the data to re-plot it in 2014b:
h1=hgopen('test.fig'); % h1 = handle to the figure
allaxes=get(h1,'children'); % allaxes = array with axes handles
for a=1:length(allaxes)
ax=allaxes(a);
allines=get(ax,'children'); % all lines in current axes
for l=1:length(allines)
lin=allines(l);
values=get(lin,'ydata'); % values of the current line
subplots{a}{l}=values;
end
end
You can then use the subplots cell array to make the plots again by hand. It is a boring way to do it, but may be worth trying if re-generating the output takes very long.

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;