I have script that calls a function in Matlab.
The function creates a figure.
I wanted 2 figures, one that is produced by the function.
The second figure that is the exact copy of that figure produced by the function.
I do not want to rerun the function to obtain the figure.
Here is my code so far:
new_handle=copyobj(2,figure(2));
I tried to use the child and parent commands too but kept getting errors and the script would not run.
You can do it with copyobj. You only need a handle to the old axis and a handle to the new figure:
plot(1:8,randn(1,8)) %// example plot
a = gca; %// get handle to axis
f = figure; %// new figure
copyobj(a,f) %// copy axis and its children to new figure
Related
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:
I am trying to create a smaller plot within a plot in MATLAB, for example like the image of this MATLAB File Exchange Upload.
There, two figures are created and then both of them are plotted in one figure.
My problem however is that I already have two MATLAB figures from earlier simulations and I need to embed one figure into the other one, i.e., one would be small and the other plot would be big but in the same graph. Could someone suggest an easy way to do this?
This can be done using the copyobj function. You'll need to copy the Axes object from one figure to the other:
f(1) = openfig('fig1.fig');
f(2) = openfig('fig2.fig');
ax(1) = get(f(1),'CurrentAxes'); % Save first axes handle
ax(2) = copyobj(get(f(2),'CurrentAxes'),f(1)); % Copy axes and save handle
Then you can move and resize both axes as you like, e.g.
set(ax(2),'Position', [0.6, 0.6, 0.2, 0.2]);
I used the plot command to plot a figure and then changed lots of its properties using set command. I also store the handle of the plot (say h1).
What I need is to use the handle to plot the same figure again later in my code. I checked the plot command and did not find any version that accepts handle. I also thought of getting the Xdata and Ydata and use them to re-plot the same figure.
What is the simplest solution?
Edit 1: A working sample code based on copyobj that PeterM suggested.
hf(1) = figure(1);
plot(peaks);
hf(2) = figure(2);
plot(membrane);
hf(3) = figure(3);
ha(1) = subplot(1,2,1);
ha(2) = subplot(1,2,2);
for i = 1:2
hc = get(hf(i),'children');
hgc = get(hc, 'children');
copyobj(hgc,ha(i));
end
Edit 2: I also found this function that can copy figures (including legend) into a subplot.
I have run into this situation before. Depending on what you are trying to do the function copyobj may be appropriate. This function lets you take the contents of one axes and copy it to a new figure.
Improving #PeterM nice answer, one easier way would be:
fig2H=copy(gcf) % or change gcf to your figure handle
But it depends on what you want, if you want only the axes, or the whole figureā¦ (btw, it doesn't seem to copy the legend handle).
You can use saveas to save the figure in a file, and the open to load the exact same figure from this file.
This would be the laziest way to accomplish what you want.
% Sample plot
f1 = figure(1);
plot(0:0.1:2*pi, sin(0:0.1:2*pi));
f2 = figure(2);
% The code you need
saveas(f1, 'temp.fig')
f2 = hgload('temp.fig')
delete('temp.fig')
I have used the function figs2subplots (given in Edit2 in the original question) - it does the work and is very easy to use.
I need a help with MatLab GUI .
I have a GUI with an axes on it,
and a function plotData(axes,data) which has axes as parameter.
The GUI has a button "plot Data".
How can I do the following:
When the button is clicked, call the function plotData with the parameter axes1 and the data that I want to plot?
I want the plot to be directed to axes1 which exists in the GUI.
It's suppose to be simple, but when I send the axes as parameter it doesn't plot on the GUI, or maybe it does but I cant see it.
It works fine for me without the function: just to plot the data. but to plot the data it's not 1 row :).
i tried calling ax which storing the GUI's axes handle on different M file, but since i call it as a function from different M file nothing happens with the GUI axes handle but it also not returning any error.
Side remark: Your question is a bit unclear: if you added small code snippet to illustrate what you have tried, better answers could be provided.
To the question at hand:
Have you tried directing the plot to axis1 in plotData?
function [] = plotData( ax, data )
% make ax the current axes for plot
axes( ax );
% continue with plotting the data
% ...
You can achieve the effect of axes( ax ); in a more efficient way through the specific plot commands you are using.
For example, if you are using simple plot
plot( ax, data ); % plots data to axes ax
check the documentation of the specific plot command you are using for the axes argument.
I have a function, myFunkyFigure, that takes in data, does some funky things, and returns an axis object for the figure it produces.
I would like to be able to invoke this function twice, creating two different figures:
fig(1) = myFunkyFigure(dataSet1);
fig(2) = myFunkyFigure(dataSet2);
Then I would like to put them into a subplot together.
Note that, because of the funkiness of myFunkyFigure, the following does not work.
subplot(2,1,1);
myFunkyFigure(dataSet1);
subplot(2,1,2);
myFunkyFigure(dataSet2);
I believe that I need something along the lines of copyobj, but I haven't been able to get that to work (I tried following a solution in Stack Overflow question Producing subplots and then combine them into a figure later in MATLAB but to no avail).
Obviously, we don't know how "funky" your figures are, but it should be noted in such a case that the cleanest solution would be to modify the function myFunkyFigure such that it accepts additional optional arguments, specifically the handle of an axes in which to place the plot it creates. Then you would use it like so:
hSub1 = subplot(2,1,1); %# Create a subplot
myFunkyFigure(dataSet1,hSub1); %# Add a funky plot to the subplot axes
hSub2 = subplot(2,1,2); %# Create a second subplot
myFunkyFigure(dataSet2,hSub2); %# Add a funky plot to the second subplot axes
The default behavior of myFunkyFigure (i.e. no additional arguments specified) would be to create its own figure and place the plot there.
However, to answer the question you asked, here's a way to accomplish this given that you are outputting the axes handles (not the figure handles) in the vector fig (note: this is basically the same solution as the one given in the other question, but since you mention having trouble adapting it I thought I'd reformat it to better fit your specific situation):
hFigure = figure(); %# Create a new figure
hTemp = subplot(2,1,1,'Parent',hFigure); %# Create a temporary subplot
newPos = get(hTemp,'Position'); %# Get its position
delete(hTemp); %# Delete the subplot
set(fig(1),'Parent',hFigure,'Position',newPos); %# Move axes to the new figure
%# and modify its position
hTemp = subplot(2,1,2,'Parent',hFigure); %# Make a new temporary subplot
%# ...repeat the above for fig(2)
The above will actually move the axes from the old figure to the new figure. If you want the axes object to appear in both figures, you can instead use the function COPYOBJ like so:
hNew = copyobj(fig(1),hFigure); %# Copy fig(1) to hFigure, making a new handle
set(hNew,'Position',newPos); %# Modify its position
Also note that SUBPLOT is only used here to generate a position for the tiling of the axes. You could avoid the need to create and then delete subplots by specifying the positions yourself.
The code from gnovice didn't work for me.
It seemed that a figure couldn't be made the child of another figure. For example hNew = copyobj(fig(1),hFigure); gave the error
Error using copyobj
Object figure[1] can not be a child of parent
figure[1]
Instead, I had to make the axes children of the new figure. This is the function I came up with
function []= move_to_subplots(ax,a,b)
% %
% Inputs:
% inputname:
% Outputs:
% name: description type units
% saved data: (does this overwrite a statically named file?)
% plots:
%
% Standard call:
%
%
% Written by C. Hogg Date 2012_06_01
%
%
debugmode=0;
hFigure=figure();
if ~exist('a')
a=ceil(sqrt(length(ax)));
end
if ~exist('b')
b=1;
end
if a*b<length(ax)|~exist('a')|~exist('b')
disp('Auto subplot sizing')
b=ceil(length(ax)/a);
end
for i=1:length(ax)
hTemp = subplot(a,b,i,'Parent',hFigure); %# Make a new temporary subplot
newPos = get(hTemp,'Position'); %# Get its position
delete(hTemp);
hNew = copyobj(ax(i),hFigure);
set(hNew,'Position',newPos)
end
%% Debug. Break point here.
if debugmode==1; dbstop tic; tic; dbclear all;end
end
This seems to work for me.