I would like to keep data from figures using gcf. However, when I close the figure, I lose all the data stored into my variable.
map = randn(10,10);
figure; imagesc(map);
fig = gcf; % I have the data stored into fig
close all;
fig; % Error : handle to deleted Figure
How can I keep data from gcf even if the figure is closed.
You could save your figure as file using saveas before closing it.
When you need it again, you can reload it with open.
Full example:
map = randn(10,10);
figure; imagesc(map);
fig = gcf;
%% Save figure in file 'MyFigureFile.fig'
saveas( fig, 'MyFigureFile', 'fig')
close all;
%% Load figure from file 'MyFigureFile.fig'
open( 'MyFigureFile.fig' );
Other Option:
You could simply hide the figure instead of closing it using fig.Visible = false or fig.Visible = 'off' as suggested in Delete object handle and keep variable in MATLAB.
Related
I have a boxplot that is saved as a figure in Matlab. Unfortunately, I do not have the original data. How do I retrieve the data using code or the user interface?
You may be more precise on your question but here is an example with a simple plot. It shoule be the same with boxplot. It is all about getting axes children.
open myfig.fig; % open your fig file
h = gca; % get the handle of the current axes
hPlot = h.Children; % The children of the axes should be the plot line
XData = hPlot.XData;
YData = hPlot.YData;
I am going to save an image in the GUI to a sperate figure. Some of codes relevant are as follows:
axes(handles.axes1); %axes object
subplot(131); imshow(tempData(:,:,1),[]); title('I1');
subplot(132); imshow(tempData(:,:,2),[]); title('I2');
subplot(133); imshow(tempData(:,:,3),[]); title('I3');
%The three images are displayed in the GUI
% saved to a new figure
handles.axes1
figurenew = figure;
copyobj(handles.axes1,figurenew);
Then, there is an error when running the code:
Error using copyobj
Copyobj cannot create a copy of an invalid handle.
Does that means the handle handle.axes1 no longer exist? Then how to modify the codes to save the displayed image in the GUI?
Each subplot has its own Axes object.
You can get this Axes object by writing as follow.
figure;
axes1 = subplot(131);
Then you can copy the object as you wrote.
figurenew = figure;
copyobj( axes1, figurenew );
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.
Let's say I have two figures stored in separate files A.fig and B.fig which contain two separate plots. Is there a way to load A.fig and then do something like hold on and then load B.fig in the figure created for A.fig so that I have both plots in the same axes?
I think the question is not really a duplicate of this one. The OP does not ask for a way to extract the data but for a way to combine the two stored figures. Admittedly, he could extract the data and plot it again. But there is a more elegant solution...
The actual plots are children of axes which is a child of figure. Therefore you can achieve what you want by copying the children of the second axes into the first axes with copyobj. Before that, load the figures with openfig. This method has the advantage to copy different types of 'plots' (line, area, ...).
The code to copy from B.fig to A.fig is as follows and works starting from R2014b:
fig1 = openfig('A');
fig2 = openfig('B', 'invisible');
copyobj(fig2.Children.Children, fig1.Children);
If you have a Matlab version prior to R2014b, you need to use the set and get functions since you cannot use .-notation. More information can be found here. You can either use gca to get the current axes after loading the figure like this:
fig1 = openfig('A');
ax1 = gca;
fig2 = openfig('B', 'invisible');
ax2 = gca;
copyobj(get(ax2,'children'), ax1);
... or get them manually from the figure-handle like this:
fig1 = openfig('A');
fig2 = openfig('B', 'invisible');
copyobj(get(get(fig2,'children'),'children'), get(fig1,'children'));
The following script creates two figures and then applies the above code to combine them.
If you are have Matlab version R2013b or higher, replace hgsave with savefig as suggested in the documentation.
%% create two figure files
x = linspace(0,2*pi,100);
figure; hold on;
plot(x,sin(x),'b');
area(x,0.5*sin(x));
set(gca,'xlim',[0,2*pi]);
hgsave('A');
figure; hold on;
plot(x,cos(x),'r');
area(x,0.5*cos(x),'FaceColor','r');
hgsave('B');
%% clear and close all
clear;
close all;
%% copy process
fig1 = openfig('A');
fig2 = openfig('B', 'invisible');
copyobj(get(get(fig2,'children'),'children'), get(fig1,'children'));
close(fig2);
This gives the following result if manually combined in subplots:
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