Combine figures with subplots into one figure - matlab

Having done several simulations on a cluster, where each simulation saves a figure, I want to combine these figures into a single figure.
For ease, assume we have the two figures:
x = 0:0.01:.2;
subplot(1,3,1)
plot(x,sin(x))
legend('sin(x)')
subplot(1,3,2)
plot(x,cos(x))
legend('cos(x)')
subplot(1,3,3)
plot(x,tan(x))
legend('tan(x)')
and
x = 0:0.01:.2;
subplot(1,3,1)
plot(x,x,'r')
legend('x')
subplot(1,3,2)
plot(x,1-x.^2/2,'r')
legend('1-x.^2/2')
subplot(1,3,3)
plot(x,x,'r')
legend('x')
saved as figure1.fig and figure2.fig. I would now like to combine these two plots into a single figure with 3 subplots, the same colouring and legends. Is there an easy way to do this?

Open both the figures and copy the objects of one figure to the other.
hf1 = openfig('figure1.fig');
hf2 = openfig('figure2.fig'); set(hf2, 'Visible', 'off');
for k=1:numel(hf1.Children)
copyobj(hf2.Children(k).Children, hf1.Children(k)); %Copying objects to figure1
end
Result for the provided sample data is:
The plots may be too similar to be noticed which is due to the provided sample data itself.

From the figure menu File -> Generate Code ..., you can generate code to create the figure. Then you can modify it (subplot index and location) according to your need to combine with another figure.
I did not a find a command to generate code through.

Related

Multiple Subplots with (Sub-)Subplots (MATLAB)

I aim to create 14 subplots with four figures in each subplot. Unfortunately, I do not have any example code to show, as I have not a clue how to go about this. A couple ideas that have popped into my head about how I can go about accomplishing this. One is to create multiple figures separately, then merge them into a single figure. Another is to create subplots with multiple subplots nested inside of them; however, again, I have not a clue how I could go about accomplishing this.
You'll probably find that you are trying to fit too much data onto one figure, and the plots will be too small to see anything of interest. However, a techniques that works, and will give you the option of having individual figures, and combining them into one figure if you wish, is to use individual figures each with a panel on it, then use copyobj to copy to your main figure.
For example,
% Create first figure
hf_sub(1) = figure(1);
hp(1) = uipanel('Parent',hf_sub(1),'Position',[0 0 1 1]);
subplot(2,2,1,'Parent',hp(1));
plot(1:10);
subplot(2,2,2,'Parent',hp(1));
surf(peaks);
subplot(2,2,3,'Parent',hp(1));
membrane;
subplot(2,2,4,'Parent',hp(1));
plot(rand(1,100));
% Create second figure
hf_sub(2) = figure(2);
hp(2) = uipanel('Parent',hf_sub(2),'Position',[0 0 1 1]);
subplot(2,2,1,'Parent',hp(2));
histogram(randn(1,1000));
subplot(2,2,2,'Parent',hp(2));
membrane
subplot(2,2,3,'Parent',hp(2));
surf(peaks)
subplot(2,2,4,'Parent',hp(2));
plot(-(1:10));
% Create combined figure
hf_main = figure(3);
npanels = numel(hp);
hp_sub = nan(1,npanels);
% Copy over the panels
for idx = 1:npanels
hp_sub(idx) = copyobj(hp(idx),hf_main);
set(hp_sub(idx),'Position',[(idx-1)/npanels,0,1/npanels,1]);
end
You may need to be more careful with positioning of the panels, and may want to create the individual figure with their visibility set to off, but the above gives the main idea.

Two saved figures, want them to show in a single graph in MATLAB

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:

Plot within a plot in MATLAB

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

grouped scatterhist in subplot in matlab

I am trying to make subplots using the grouped scatterhist function in matlab.
subplot(2,2,1)
scatterhist(x,y,'Group',factor)
subplot(2,2,2)
scatterhist(x,y,'Group',factor)
This makes one normal sized plot of the second subplot. Any ideas?
scatterhist doesn't interact well with subplot, so you have to find ways around that.
Here is a way of doing it with uipanel.
% create two separate figures with the two scatterplots in
h1 = figure
scatterhist(x,y,'Group',factor)
h2 = figure
scatterhist(x,y,'Group',factor)
% create third figure split into two uipanels
h3 = figure
u1 = uipanel('position',[0,0,0.5,1]);
u2 = uipanel('position',[0.5,0,0.5,1);
% get all children from each figure and move to the uipanels
set(get(h1,'Children'),'parent',u1);
set(get(h2,'Children'),'parent',u2);
%close unneeded figures
close(h1,h2)
If you wanted to do a lot of these, you might want to create a function that works out the right position values depending on how many subplots you want in the figure.

How to create a new figure in MATLAB?

Usually when I plot in MATLAB, it always draws on the same figure. How do I make it draw in a new figure?
I know it is pretty elementary, but I'm not finding it using Google Search.
figure;
plot(something);
or
figure(2);
plot(something);
...
figure(3);
plot(something else);
...
etc.
While doing "figure(1), figure(2),..." will solve the problem in most cases, it will not solve them in all cases. Suppose you have a bunch of MATLAB figures on your desktop and how many you have open varies from time to time before you run your code. Using the answers provided, you will overwrite these figures, which you may not want. The easy workaround is to just use the command "figure" before you plot.
Example: you have five figures on your desktop from a previous script you ran and you use
figure(1);
plot(...)
figure(2);
plot(...)
You just plotted over the figures on your desktop. However the code
figure;
plot(...)
figure;
plot(...)
just created figures 6 and 7 with your desired plots and left your previous plots 1-5 alone.
The other thing to be careful about, is to use the clf (clear figure) command when you are starting a fresh plot. Otherwise you may be plotting on a pre-existing figure (not possible with the figure command by itself, but if you do figure(2) there may already be a figure #2), with more than one axis, or an axis that is placed kinda funny. Use clf to ensure that you're starting from scratch:
figure(N);
clf;
plot(something);
...
As has already been said: figure will create a new figure for your next plots. While calling figure you can also configure it. Example:
figHandle = figure('Name', 'Name of Figure', 'OuterPosition',[1, 1, scrsz(3), scrsz(4)]);
The example sets the name for the window and the outer size of it in relation to the used screen.
Here figHandle is the handle to the resulting figure and can be used later to change appearance and content. Examples:
Dot notation:
figHandle.PaperOrientation = 'portrait';
figHandle.PaperUnits = 'centimeters';
Old Style:
set(figHandle, 'PaperOrientation', 'portrait', 'PaperUnits', 'centimeters');
Using the handle with dot notation or set, options for printing are configured here.
By keeping the handles for the figures with distinc names you can interact with multiple active figures. To set a existing figure as your active, call figure(figHandle). New plots will go there now.
Another common option is when you do want multiple plots in a single window
f = figure;
hold on
plot(x1,y1)
plot(x2,y2)
...
plots multiple data sets on the same (new) figure.
As simple as this-
figure, plot(yourfigure);