How can I suppress the display of a figure window while keeping the plotting in the background for saving the resulting plot at the end of run? What is the best practice to do this? At present, my code is like this:
showPlot = 1; % switch to turn plotting on/off
fig = figure(1); clf; hold on;
lineHandle = line(nan, nan);
total = 0;
for i = 1:10000
% long calculation
total = total + 1;
set(0, 'CurrentFigure', fig);
xlim([0, total]);
x = [get(lineHandle, 'XData'), total];
y = [get(lineHandle, 'YData'), rand()];
set(lineHandle, 'XData', x, 'YData', y);
drawnow;
end
% saveas(gcf, file, 'png');
I want to set up the code in such a way that when I set showPlot to 0, the figure window is not shown but the plot is saved to file.
To make the current figure not visible:
set(gcf,'visible','off')
From the MathWorks-reference:
To avoid showing figures in MATLAB you can start MATLAB using the noFigureWindows option. This option is not available on UNIX.
matlab -noFigureWindows
As an alternative you can change the default figure properties of the MATLAB root object:
set(0,'DefaultFigureVisible','off')
If you want to temporarily suppress new figures that should be accesable later in the same session you can save the figure handle:
set(0,'DefaultFigureVisible','off');
%create invisible figure 1
h(1)=figure;
%create invisible figure 2
h(2)=figure;
set(0,'DefaultFigureVisible','on');
%show figure 1
figure(1)
By the way, close all closes all currently open figures.
The other answers were not working for me on R2015b on Ubuntu, my figure window would always show up.
I am processing 100+ files and the figure window popping up prevents me from using my computer while processing the files.
Here's a workaround, launch matlab without a display:
matlab -nodesktop -nodisplay
and this will prevent figure windows from showing up. Programmatically saving the figure to a file still works.
As answered earlier, to suppress displaying figures during instantiation first call
set(0, 'DefaultFigureVisible', 'off');
% or, if post Matlab R2014b
set(groot, 'DefaultFigureVisible', 'off');
After this call, creation of new figures in a script will not result in a visible window popping up. Naturally, the way to revert this setting is
set(0, 'DefaultFigureVisible', 'on');
% or, if post Matlab R2014b
set(groot, 'DefaultFigureVisible', 'on');
The "gotcha" is that activating an existing figure for further manipulation will result in a visible window - if done incorrectly:
% suppress visible plot window creation
set(groot, 'DefaultFigureVisible', 'off');
figure(1); % will not result in a visible window
plot(0:.01:pi,sin(0:.01:pi));
hold on
figure(2); % still no visible window
plot(0:.01:10,(0:.01:10).^2);
% so far so good
% ... other statements ...
% select figure 1 to add to it:
figure(1); % visible window appears!
plot(0:.01:pi,cos(0:.01:pi));
hold off;
% ...
The workaround is to use another set command to select existing figures:
set(groot, 'DefaultFigureVisible', 'off');
figure(1); % will not result in a visible window
plot(0:.01:pi,sin(0:.01:pi));
hold on
figure(2); % still no visible window
plot(0:.01:10,(0:.01:10).^2);
set(groot, 'CurrentFigure', 1); % still no visible window
% plot commands will apply to figure 1
plot(0:.01:pi,cos(0:.01:pi));
hold off
% ...
Regardless of the setting of 'DefaultFigureVisible', calling
figure(h);
where h is a handle or integer for an existing plot window causes that window to become active and visible. Thus, one can make all plots visible at the bottom of a script this way:
fh = get(groot, 'Children');
for x = 1:numel(fh)
figure(fh(x));
end
Related
function plot2(x)
hold on
fig = gcf();
ax = gca();
plot(ax, x)
fig.Visible = true;
figure('Visible', 'off')
hold off
end
Why does
>> plot2([1 2]); plot2([2 1])
create two figures, but
>> plot2([1 2])
>> plot2([2 1])
one? We have
plot2() <=> use 1 existing figure, create 1 new figure
>> plot2(); plot2() <=> use figure X, create figure Y, use figure Y, create figure Z.
>> plot2() >>plot2() <=> use figure X, create figure Y. use figure Y? create figure Z?
disp(gcf) before hold off show that new figs are being created in both cases, as in Figure (25), Figure (26).
Note that calling plot2([1 2]); drawnow(); plot2([2 1]) on a single line uses one figure the same as two separate plot2 calls. So at a high level it's likely due to the graphics buffer not being flushed when calling both on a single line without drawnow.
However, debugging we can see this is caused by the slightly odd order of operations called by your plot2 function, which has ambiguous handling of figures by relying on gcf and using calls to hold out-of-order and without specifying the hold target axes.
In the below lines, where I've written a code line it as an extract from plot2 during a given command call:
>> plot2([1 2]); plot2([2 1])
% Calling through "plot2([1 2])"
hold on % creates a figure and axes if one doesn't exist, or hold current
fig = gcf(); % gets the figure referenced by "hold"
ax = gca; % gets the axes referenced by "hold"
plot(ax,x) % plots on these axes
fig.Visible = true; % make the current figure visible
figure('Visible','off') % Create NEW figure, hidden. At this point you have 2 figures
hold off % does NOTHING, sets hold to "off" for new (invisible)
% figure which is the default anyway
% Calling through "plot2([2 1])"
hold on % holds "on" the CURRENT figure. This will depend whether the graphics buffer
% has been flushed. If not then the current figure is the hidden one created
% in the previous call, if it has then the current figure is the most recent
% visible figure. This is *not* specifically noted in the docs.
fig = gcf(); % gets the same figure referenced by "hold"
ax = gca; % gets the same axes referenced by "hold"
plot(ax,x) % plots on these axes
fig.Visible = true; % make the same "current" figure as above visible. When running with a
% graphics flush in between, this figure will already be visible
% due to the above behaviour
figure('Visible','off') % Create ANOTHER NEW figure, hidden.
% At this point you will have 3 figures!
hold off % does NOTHING, sets hold to "off" for new (invisible)
% figure which is the default anyway
You can verify my last comment about ending up with 3 figures using allFig = findall(0,'type','figure'); which will show all current figure objects including those which are hidden.
I'm trying to create an animation file in MATLAB from a figure with 2 subplots using the VideoWriter. However, the avi file that I get includes only one of the subplots.
Here is the code:
clc
clear
vidObj = VideoWriter('randdata');
open(vidObj)
figure (1)
for i = 1:100
clf
subplot(1,2,1)
imagesc(rand(100))
subplot(1,2,2)
imagesc(rand(100))
drawnow
CF = getframe;
writeVideo(vidObj,CF);
end
There must be something simple going wrong here but I don't know what. I would like to capture the entire figure.
The documentation for getframe states in the first line:
F = getframe captures the current axes
So it's capturing the axes, not figure.
You want to use it as also specified in the documentation
F = getframe(fig) captures the figure identified by fig. Specify a figure if you want to capture the entire interior of the figure window, including the axes title, labels, and tick marks. The captured movie frame does not include the figure menu and tool bars.
So your code should be
clc; clear
vidObj = VideoWriter('randdata');
open(vidObj);
figure(1);
for ii = 1:100
clf
subplot(1,2,1)
imagesc(rand(100))
subplot(1,2,2)
imagesc(rand(100))
drawnow;
% The gcf is key. You could have also used 'f = figure' earlier, and getframe(f)
CF = getframe(gcf);
writeVideo(vidObj,CF);
end
For ease, you might want to just get a File Exchange function like the popular (and simple) gif to create an animated gif.
I am creating some figures in MATLAB and automatically save them to files. The problem that by definition the images are small. A good way to solve my problem by hand is to create an image (figure), maximize it, and save to a file.
I am missing this step of automatically maximize a figure.
Any suggestions?
Up till now I only found this:
http://answers.yahoo.com/question/index?qid=20071127135551AAR5JYh
http://www.mathworks.com/matlabcentral/newsreader/view_thread/238699
but none are solving my problem.
This worked for me:
figure('units','normalized','outerposition',[0 0 1 1])
or for current figure:
set(gcf,'units','normalized','outerposition',[0 0 1 1])
I have also used MAXIMIZE function on FileExchange that uses java. This is true maximization.
For an actual Maximize (exactly like clicking the maximize button in the UI of OS X and Windows)
You may try the following which calls a hidden Java handle
figure;
pause(0.00001);
frame_h = get(handle(gcf),'JavaFrame');
set(frame_h,'Maximized',1);
The pause(n) is essential as the above reaches out of the Matlab scape and is situated on a separate Java thread. Set n to any value and check the results. The faster the computer is at the time of execution the smaller n can be.
Full "documentation" can be found here
As of R2018a, figure as well as uifigure objects contain a property called WindowState. This is set to 'normal' by default, but setting it to 'maximized' gives the desired result.
In conclusion:
hFig.WindowState = 'maximized'; % Requires R2018a
Furthermore, as mentioned in Unknown123's comments:
Making figures maximized by default is possible using:
set(groot, 'defaultFigureWindowState', 'maximized');
Maximizing all open figures is possible using:
set(get(groot, 'Children'), 'WindowState', 'maximized');
More information about 'WindowState' as well as other properties controlling figure appearance can be found in this documentation page.
Finally, to address your original problem - if you want to export the contents of figures to images without having to worry about the results being too small - I would highly recommend the export_fig utility.
To maximize the figure, you can mimic the sequence of keys you would actually use:
ALT-SPACE (as indicated here) to access the window menu; and then
X to maximize (this may vary in your system).
To send the keys programmatically, you can use a Java-based procedure similar to this answer, as follows:
h = figure; %// create figure and get handle
plot(1:10); %// do stuff with your figure
figure(h) %// make it the current figure
robot = java.awt.Robot;
robot.keyPress(java.awt.event.KeyEvent.VK_ALT); %// send ALT
robot.keyPress(java.awt.event.KeyEvent.VK_SPACE); %// send SPACE
robot.keyRelease(java.awt.event.KeyEvent.VK_SPACE); %// release SPACE
robot.keyRelease(java.awt.event.KeyEvent.VK_ALT); %// release ALT
robot.keyPress(java.awt.event.KeyEvent.VK_X); %// send X
robot.keyRelease(java.awt.event.KeyEvent.VK_X); %// release X
VoilĂ ! Window maximized!
As it is proposed by an author above, if you want to simulate clicking the "maximize" windows button, you can use the code that follows. The difference with the mentionned answer is that using "drawnow" instead of "pause" seems more correct.
figure;
% do your job here
drawnow;
set(get(handle(gcf),'JavaFrame'),'Maximized',1);
imho maximizing the figure window is not the best way to save a figure as an image in higher resolution.
There are figure properties for printing and saving. Using these properties you can save files in any resolution you want. To save the files you have to use the print function, because you can set an dpi value. So, firstly set the following figure properties:
set(FigureHandle, ...
'PaperPositionMode', 'manual', ...
'PaperUnits', 'inches', ...
'PaperPosition', [0 0 Width Height])
and secondly save the file (for example) as png with 100dpi ('-r100')
print(FigureHandle, Filename, '-dpng', '-r100');
To get a file with 2048x1536px set Width = 2048/100 and Height 1536/100, /100 because you save with 100dpi. If you change the dpi value you also have to change the divisor to the same value.
As you can see there is no need for any extra function from file exchange or java-based procedure. In addition you can choose any desired resolution.
you can try this:
screen_size = get(0, 'ScreenSize');
f1 = figure(1);
set(f1, 'Position', [0 0 screen_size(3) screen_size(4) ] );
%% maximizeFigure
%
% Maximizes the current figure or creates a new figure. maximizeFigure() simply maximizes the
% current or a specific figure
% |h = maximizeFigure();| can be directly used instead of |h = figure();|
%
% *Examples*
%
% * |maximizeFigure(); % maximizes the current figure or creates a new figure|
% * |maximizeFigure('all'); % maximizes all opened figures|
% * |maximizeFigure(hf); % maximizes the figure with the handle hf|
% * |maximizeFigure('new', 'Name', 'My newly created figure', 'Color', [.3 .3 .3]);|
% * |hf = maximizeFigure(...); % returns the (i.e. new) figure handle as an output|
%
% *Acknowledgements*
%
% * Big thanks goes out to Yair Altman from http://www.undocumentedmatlab.com/
%
% *See Also*
%
% * |figure()|
% * |gcf()|
%
% *Authors*
%
% * Daniel Kellner, medPhoton GmbH, Salzburg, Austria, 2015-2017
%%
function varargout = maximizeFigure(varargin)
warning('off', 'MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame')
% Check input variables
if isempty(varargin)
hf = gcf; % use current figure
elseif strcmp(varargin{1}, 'new')
hf = figure(varargin{2:end});
elseif strcmp(varargin{1}, 'all')
hf = findobj('Type', 'figure');
elseif ~isa(varargin{1}, 'char') && ishandle(varargin{1}) &&...
strcmp(get(varargin{1}, 'Type'), 'figure')
hf = varargin{1};
else
error('maximizeFigure:InvalidHandle', 'Failed to find a valid figure handle!')
end
for cHandle = 1:length(hf)
% Skip invalid handles and plotbrowser handles
if ~ishandle(cHandle) || strcmp(get(hf, 'WindowStyle'), 'docked')
continue
end
% Carry the current resize property and set (temporarily) to 'on'
oldResizeStatus = get(hf(cHandle), 'Resize');
set(hf(cHandle), 'Resize', 'on');
% Usage of the undocumented 'JavaFrame' property as described at:
% http://undocumentedmatlab.com/blog/minimize-maximize-figure-window/
jFrame = get(handle(hf(cHandle)), 'JavaFrame');
% Due to an Event Dispatch thread, the pause is neccessary as described at:
% http://undocumentedmatlab.com/blog/matlab-and-the-event-dispatch-thread-edt/
pause(0.05)
% Don't maximize if the window is docked (e.g. for plottools)
if strcmp(get(cHandle, 'WindowStyle'), 'docked')
continue
end
% Don't maximize if the figure is already maximized
if jFrame.isMaximized
continue
end
% Unfortunately, if it is invisible, it can't be maximized with the java framework, because a
% null pointer exception is raised (java.lang.NullPointerException). Instead, we maximize it the
% straight way so that we do not end up in small sized plot exports.
if strcmp(get(hf, 'Visible'), 'off')
set(hf, 'Units', 'normalized', 'OuterPosition', [0 0 1 1])
continue
end
jFrame.setMaximized(true);
% If 'Resize' will be reactivated, MATLAB moves the figure slightly over the screen borders.
if strcmp(oldResizeStatus, 'off')
pause(0.05)
set(hf, 'Resize', oldResizeStatus)
end
end
if nargout
varargout{1} = hf;
end
This is the shortest form
figure('Position',get(0,'ScreenSize'))
I recommend the set command to change MenuBar and Toolbar properties of your figure. The set command is more versatile because it works for older and newer versions of Matlab.
fig = figure(1);
set(fig, 'MenuBar', 'none');
set(fig, 'ToolBar', 'none');
Now you can use set again to make your figure full screen.
set(fig, 'Position', get(0,'Screensize'));
Note that if you make the figure full screen first, and then remove the MenuBar and Toolbar, the figure will not be full screen, so make sure to run these in the correct order.
I am trying to plot with hidden Matlab figures to speed up my plotting:
a=1:10; b=-a;
% make invisible plot window
f = figure('visible','off');
g = figure('visible','off');
% figure makes the plot visible again
figure(f)
plot(a)
saveas(f,'newout','fig')
figure(g)
plot(b)
saveas(g,'newout2','fig')
%% load saved figures
openfig('newout.fig','new','visible')
openfig('newout2.fig','new','visible')
The problem is the figure(f) command that makes the plot window visible again.
The code plots without figure window when I only have one plot and figure(f) is not called.
I just learned that instead of calling figure(f) one should use set:
set(0, 'currentfigure', g);
This will change the current figure handle without changing its visibility.
The corrected version works as expected:
a=1:10; b=-a;
% make invisible plot window
f = figure('visible','off');
g = figure('visible','off');
% figure makes the plot visible again
set(0, 'currentfigure', f);
plot(a)
saveas(f,'newout','fig')
set(0, 'currentfigure', g);
plot(b)
saveas(g,'newout2','fig')
%% load saved figures
close all
openfig('newout.fig','new','visible')
openfig('newout2.fig','new','visible')
I would suggest making a whole new plot window. By doing that you will get two different plots, and as you say that only one plot works, i think it could work.
An alternative solution is to reference the axes within the plot command (instead of changing the current figure before plot):
a=1:10; b=-a;
f = figure('visible','off');
fax = gca; %// get handle to axes of figure f
g = figure('visible','off');
gax = gca; %// get handle to axes of figure g
plot(fax, a) %// plot in axes of figure f
saveas(f,'newout','fig')
plot(gax, b) %// plot in axes of figure g
saveas(g,'newout2','fig')
openfig('newout.fig','new','visible')
openfig('newout2.fig','new','visible')
I got a GUI showing several plots. now i'd like to get one of these... "main_plot" for example (the entire figure with title, axes-descriptions AND the legend) and export it to a file. this is what i got so far:
function main_plot_exp_Callback(hObject, eventdata, handles)
f_tmp = figure('visible','off');
set(f_tmp,'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
copyobj(handles.main_plot,f_tmp);
set(gca,'Position',[0.16125 0.09 0.684375 0.84],...
'GridLineStyle','--');
print(f_tmp, '-djpeg', 'name', '-r300');
close(f_tmp);
generally works like a charm EXCEPT for the damn legend, which appears to get lost in the process. any suggestions or ideas? thanks in advance!
(side question: is there anything like "gcf" only for a CERTAIN and not the current figure?)
I tried your procedure and faced no problem (my matlab: 8.2.0.701 (R2013b))
The best you could do as follow
hSome = findobj(handles.main_plot);
get(hSome,'Tag')
Results should yield one "legend" string. If not, replace findobj with findall. Otherwise your legend handle is stocked somewhere else and you need to look deeper into your GUI.
I had the same problem with the legend being lost in the process. The best I could do to overcome this was to re-create the legend in the new figure before saving it. Here an example of the code I used:
% find the legend(s) - I suppose in the following that there is only one legend in the GUI
L1 = findobj(handles.figure1,'tag','legend'); % where handles.figure1 is the GUI figure handle
% retrieve the legend strings and location
legendstr=get(L1,'String');
legendloc=get(L1,'Location');
% handle to the GUI axes to be saved
ax = handles.axes1;
% create a new figure
fig = figure('Units','centimeters','outerposition',[2 2 17 17]);
% copy the GUI axes into the new figure
new_axes = copyobj(ax, fig);
set(new_axes,'Units','normalized','Position',[0.1 0.1 0.8 0.8]);
% recreate the legend
legend(new_axes,legendstr,'Location',legendloc);
%save the files in .fig and .format files (.format = .jpg, .png, ...)
hgsave(fig,[pname '\' filename]);
hgexport(fig, fname, hgexport('factorystyle'),'Format', format)
close(fig);
Assuming the axes is called main_plot, I found that the legend is referenced by:
legend(handles.main_plot)
So you would need to copy the legend with its parent axes (as a vector input) to the new figure:
copyobj([handles.main_plot legend(handles.main_plot],f_tmp);