Multiple Subplots with (Sub-)Subplots (MATLAB) - 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.

Related

matlab dynamic scrolling in figures

I've added a number of timeseries to a figures object in Matlab and plotted them as subplots on the graph to display them all together, one after the other. There can be a dynamic number of timeseries plots, I can't know in advance how many there will be.
Unfortunately what seems to be happening is that the figures plot is not expanding to include a scroll bar as new subplots are added. Is there a particular flag I'm not seeing to include this and stop the plots in my figures object from getting smaller and smaller?
As an example:
%Maximise the figure window to full screen
f = figure;
f=gcf;
f.Units='normalized';
f.OuterPosition=[0 0 1 1];
%Add a panel to the figure, we'll add subplots to this
p = uipanel('Parent',f,'BorderType','none');
p.Title = 'Examples';
p.TitlePosition = 'centertop';
p.FontSize = 12;
p.FontWeight = 'bold';
%Add a timeseries subplot to the panel
subplot((length(motifIndexAfterThresholds)*2)+1,1,1, 'Parent',p)
ts0 = timeseries(E4_hrX(startIndex:endIndex),'Name','Parent Motif');
plot(ts0)
title('Parent')
After this point I could add in as many subplots as I like, but the panel is not stretching as I'd have hoped.
If anyone can offer suggestions I'd very much appreciate it.
Anyone with the same problem, check out this (2011) blog post:
https://blogs.mathworks.com/pick/2011/11/23/scrolling-figures-guis/
It turns out that a user submitted function can provide this functionality, and all we need to do is download that .m file, include it in your Matlab path, change the function call from subplot to scrollsubplot in our code.
No idea if this will work long term, a feature like this probably should be included out of the box by matlab itself.

Combine figures with subplots into one figure

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.

Creating annotation boxes for subplots in a for-loop in Matlab

I have the following code in Matlab that runs through a for loop, reads data from a file and plots 9 different figures, that correspond to some particular "channels" in my data, so I decided to annotate them in the for loop.
clear
clc
for i=1:9
subplot(3,3,i);
hold on
x = [4 13]; % from your example
y = ([1 1]); % from your example
y2 = ([-0.4 -0.4]);
H=area(x,y,'LineStyle','none',...
'FaceColor',[1 0.949019610881805 0.866666674613953]);
H1=area(x,y2,'LineStyle','none',...
'FaceColor',[1 0.949019610881805 0.866666674613953]);
% Create textbox
annotation('textbox',...
[0.719849840255583 0.603626943005185 0.176316293929713 0.308290155440411],...
'String',{'FABLIGHT04','Channel',i},...
'FontWeight','bold',...
'FontSize',10,...
'FontName','Geneva',...
'FitBoxToText','off',...
'EdgeColor','none');
axis([0 24 -0.4 1])
set(gca,'XTick',[0:1:24])
set(gca,'YTick',[-0.4:0.2:1])
xlabel('Time (s)');
end
Initially it was giving me 9 different figures and the annotation thing worked fine. But I wanted to be able to tile them onto a subplot for easier comparison.
Since I switched over to using subplot, it does not annotate my figure properly. On opening the editing dock and generating the code, I find that matlab is plotting everything first and then just putting the annotation boxes in the same figure, one on top of the other. Looking at the code it generated, it apparently takes this part of the code:
annotation('textbox',...
[0.719849840255583 0.603626943005185 0.176316293929713 0.308290155440411],...
'String',{'FABLIGHT04','Channel',i},...
'FontWeight','bold',...
'FontSize',10,...
'FontName','Geneva',...
'FitBoxToText','off',...
'EdgeColor','none');
and does it as:
annotation(figure1,'textbox'...)
etc etc
So for all 9 text boxes, it puts them onto the same figure. I tried to do S=subplot(3,3,i) then annotation(S,'textbox') etc etc, I have also tried S(i)=subplot(3,3,i) and then annotation(S,'textbox') etc etc but nothing seems to work.
I have also tried to change the location of the box. I can't seem to figure out how to make it smaller either.
Does anyone know how to have annotation boxes in the right subplot in a for loop?
Thanks
I'm afraid annotation objects are properties of figures and NOT axes, as such its harder to customize the position of each annotation objects because no matter how many subplots you have, they are all part of the same figure and you need to specify their position relatively to the figure coordinate system.
Therefore, you can manually set the position of each text box in your code depending on the subplot it belongs to...
Simple example:
clear
clc
close all
figure('Units','normalized'); %// new figure window
for k = 1:2
str = sprintf('Subplot %d',k);
subplot(1,2,k)
plot(rand(1,10));
%// Customize position here
hAnnot(k) = annotation('textbox', [k*.4-.2 .6 .1 .1],...
'String', str,'FontSize',14);
end
Which looks like this:
Its not very elegant but I'm personally not aware of any other option if you do need to use annotations objects. A less cumbersome alternative would be to use a simple text objects, which are properties of axes and therefore much more friendly to position :)
Hope that helps!

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