How do I resize a figure window to cover the entire screen on MATLAB 2014 (b) +? [duplicate] - matlab

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.

Related

Figure behavior varies when calling custom plot on single line or multiple lines

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.

Increasing size of arrows in Nyquist plot?

Does anyone know how to increase the size of the arrows in the Nyquist plot generated by MATLAB Control System Toolbox (while keeping the line width and everything else in the figure the same)?
I noticed that you also asked the same question in MATLAB
Central. Please make sure to refer other visitors to this answer if
you found it useful.
The Bad News first
MATLAB Control System Toolbox provides the functions nyquist and nyquistplot to draw a Nyquist plot of the frequency response of a dynamic system model.
Even though these functions allow a certain level of graphical customization (units, grids, labels and basic LineSpec), they don't allow to alter the size of the arrows that appear by default in the Nyquist plot (you can read more about this here and here).
The Good News (time to hack!)
I started exploring the object hierarchy of the Nyquist plot figure and realized that the arrows that are drawn are patch objects.
How did I notice that?
First I generated a sample Nyquist plot:
sys = tf([2 5 1],[1 2 3]); % System transfer function.
nyquist(sys); % Nyquist plot.
Then I ran a brute force test!
The following test iterates through every graphics object of the Nyquist plot figure window and blinks one element in every iteration. This way I was able to visually identify the objects that were linked to the arrows, when they started blinking.
h = findall(gcf); % Find all graphics objects including hidden ones.
t = 0.5; % Time interval.
for i = 1:length(h) % Loop through every object handle.
disp(i); % Display handle array index.
pause(t); % Pause for t seconds.
status = h(i).Visible; % Copy Visible property.
if strcmp(status, 'on') % If Visible = 'on' --> Visible = 'off'
h(i).Visible = 'off';
else % If Visible = 'off' --> Visible = 'on'
h(i).Visible = 'on';
end
pause(t); % Pause for t seconds.
h(i).Visible = status; % Restore original Visible property.
pause(t); % Pause for t seconds.
end
disp('Finished!'); % Display Finished!
After running this test, I found out that h(196) and h(197) were the two arrows of the Nyquist plot, and they were patch objects.
Changing the 'LineWidth' property was the next logical step. The following piece of code is really all you need to do in order to change the size of the arrows:
sys = tf([2 5 1],[1 2 3]); % System transfer function.
nyquist(sys); % Nyquist plot.
h = findall(gcf, 'Type', 'Patch'); % Find all patch objects.
for i = 1:length(h) % Loop through every patch object handle.
h(i).LineWidth = 4; % Set the new LineWidth value.
end
This is the result:
I hope that you enjoyed the adventure! :D

Copy figure AND legend in matlab gui

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);

How to suppress figures?

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

MATLAB getframe captures whatever is on screen

I am trying to create a movie from my MATLAB plot. When I call getframe, it "usually" captures the plot image, but sometimes if there is something else active on the screen (which is normal if I continue to use the computer) it captures whatever window is active. Is there another way to grab the image of the active figure?
e.g.
fig = figure;
aviobj = avifile('sample.avi','compression','None');
for i=1:t
clf(fig);
plot(...); % some arbitrary plotting
hold on;
plot(...); % some other arbitrary plotting
axis([0 50 0 50]);
aviobj = addframe(aviobj, getframe(fig));
end
aviobj = close(aviobj);
OK, found the solution; instead of
aviobj = addframe(aviobj, getframe(fig));
sending the figure handle directly to addframe is enough:
aviobj = addframe(aviobj, fig);
The Matlab people are apparently phasing out the avifile and addframe functions in future releases, replacing them with VideoWriter and writeVideo respectively. Unfortunately, this means that the accepted answer will no longer work, since writeVideo doesn't accept the figure handle as the argument.
I've played around with it a bit, and for future reference, the same thing can be accomplished using the undocumented hardcopy function. The following code works perfectly for me, with the added benefit of not even having a plot window pop up, so it does everything completely in the background:
fig = figure('Visible','off');
set(fig,'PaperPositionMode','auto');
writerobj = VideoWriter('sample.avi','Uncompressed AVI');
open(writerobj);
for i=1:t
clf(fig);
plot(...); % some arbitrary plotting
hold on;
plot(...); % some other arbitrary plotting
axis([0 50 0 50]);
figinfo = hardcopy(fig,'-dzbuffer','-r0');
writeVideo(writerobj, im2frame(figinfo));
end
close(writerobj);
You can pass the handle of the desired figure or axis to GETFRAME to ensure that it doesn't capture another window.
I may depend on the renderer you're using. If it's 'painters', then you should be OK, but if it's anything else, such as 'OpenGL', then I think it has to get the frame data from the graphics card, which means that if you have something overlapping the window, then that may end up in the output of getframe.
As someone has already stated you don't have to use getframe, however if you insist on using it you can use
set(fig,'Renderer','zbuffer')
and this should fix your issue.
If you use getframe in many subplots, try to add at the end:
I think the get frame works fine it just the rendering a bit was unpositioned.
clf(fig)
% use 1st frame to get dimensions
[h, w, p] = size(frames(1).cdata);
hf = figure;
% resize figure based on frame's w x h, and place at (150, 150)
set(hf,'Position', [150 150 w h]);
axis off
% Place frames at bottom left
movie(hf,frames,4,30,[0 0 0 0]);
close(gcf)