Matlab plot multiple figures without window - matlab

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

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.

Animation of figure with subplots using VideoWriter in MATLAB

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.

Colorbar limits not respecting axes clims when displaying an image

Im trying to superimpose a trimesh-plot over a image imshow using hold on. This works fine so far. I'd additionally like to display a colorbar, which works too, but unfortunately it does not adjust to the range specified by caxis, does anyone have an idea how to fix this?
This is an example output: The colourbar should display a range from 1 to z, not from 0 to 60. If we remove imshow everything works fine.
Here my MCVE:
clc;clf;clear
T = [1,2,3;3,1,4]; % triangulation
X = [0,1,1,0]*300; % grid coordinates
Y = [0,0,1,1]*300;
for z = 2:20;
clf;
imshow(imread('board.tif')) % plot image (this is a built in matlab test image)
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
caxis([1,z])
colorbar
drawnow
pause(0.5)
end
This appears to be a bug in how older versions of MATLAB handled the colorbar (it's not present with HG2). The "correct" behavior would be that if you have any objects in the current axes that use scaled values, then the colorbar should respect your clims. It seems that MATLAB is using the first child in the current axes to determine whether to respect your clims or not. imshow does not use scaled CDataMapping so colorbar simply ignores your clims.
It looks like you have three options:
Use imagesc rather than imshow
clf;
imagesc(imread('board.tif'));
axis image
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
caxis([1,z])
drawnow
colorbar
drawnow
pause(0.5)
Call imshow after you've created your trisurf object
clf;
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
him = imshow(imread('board.tif'));
caxis([1,z])
drawnow
colorbar
drawnow
pause(0.5)
Set the CDataMapping property of the image object to 'scaled' (will be ignored when displaying the image since it's RGB but it will allow the colorbar to function properly)
clf;
him = imshow(imread('board.tif'));
set(him, 'CDataMapping', 'scaled')
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
caxis([1,z])
drawnow
colorbar
drawnow
pause(0.5)

Plotting in GUI of Matlab

Until now i had only 1 axis in my GUI to I used to just plot directly using plot command. Plus i need to plot these in a loop.
for i = 1:length(sig)
plot(sig(i).time,sig(i).signal,sig(i).time,updated(i).filter,)
hold on
end
Now i have 2 axes in my GUI, how can I make a certain plot appear in 1st axis and another in my 2nd axis
Now for example i need to plot the below in the 2nd axis
for i = 1:length(sig)
plot(sig(i).time,sig(i).fil,sig(i).time,updated(i).sig,)
hold on
end
Any help will be appriciated
You could specify the axes for hold and plot functions. Considering you have two axes, h1 and h2 inside your figure, you could do the following:
hold(h1, 'on')
hold(h2, 'on')
for i = 1:length(sig)
plot(h1, sig(i).time,sig(i).signal,sig(i).time,updated(i).filter)
plot(h2, sig(i).time,sig(i).fil,sig(i).time,updated(i).sig)
end

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