Large composed plots in a single subplot in Matlab - matlab

Introduction
I am currently working on a MATLAB script which handles a large plot rutine. In short I am creating a plot that consist of several other plots. Now I want this plot into a subplot with another plot. However, I cannot seem to get this working.
Code:
My first plot:
h = figure('Units', 'pixels', ...
'Position', [100 100 1000 375]);
= fill([xfit fliplr(xfit)],[meanSeq-stdSeq fliplr(meanSeq+stdSeq)],[0.7 0.7
0.7],'linestyle','none');
b = fill([xfit fliplr(xfit)],[meanMul-stdMul fliplr(meanMul+stdMul)],[0.7 0.7 0.7],'linestyle','none');
c = plot(xfit,meanSeq,'black','linewidth',1.5); %% change color or linewidth to adjust mean line
e = plot(xfit,meanSeq./7.5,'color',[0.75 0 0],'linewidth',1.5);
d = plot(xfit,meanMul,'b','linewidth',1.5); %% change color or linewidth to adjust mean line
axis([0 max(xfit) 0 max(meanSeq)+10]);
subplot(2,1,1);
and my second plot:
hTwo = figure('Units', 'pixels', ...
'Position', [100 100 1000 375]);
f = plot(xfit,meanSeq./meanMul,'linewidth',1.5);
hold on
g = plot(xfit,1/(0.01+0.99/8),'linewidth',1.5);
hij = plot(xfit,mean(meanSeq./meanMul),'linewidth',1.5);
axis([0 max(xfit) 5 8]);
subplot(2,1,2);
Question
Now, apperantly it is not possible to put these two separte plots into one subplot all I get is an empty white graph. Each plot rutine works seperatly.

You have to call the subplot(2,1,1) before you plot with plot().
As I'm not able to run your code I give you the general plan:
1- figure()
2- subplot(2,1,1)
3- plot() % plot data into first subplot
4- subplot(2,1,2)
5- plot() % plot data into second subplot

Related

Multiple x-axis and y-axis with plots in MATLAB

I am trying to follow MATLAB's documentation here Graph with Multiple x-axes and y-axes to plot with 2 x and y-axes, but instead with plots rather than lines. This is what I have so far:
clear all; close all; clc;
% Arbitrary x's and y's
x1 = [10 20 30 40];
y1 = [1 2 3 4];
x2 = [100 200 300 400];
y2 = [105 95 85 75];
figure
plot(x1,y1,'Color','r')
ax1 = gca; % current axes
ax1.XColor = 'r';
ax1.YColor = 'r';
ax1_pos = ax1.Position; % position of first axes
ax2 = axes('Position',ax1_pos,...
'XAxisLocation','top',...
'YAxisLocation','right',...
'Color','none');
%line(x2,y2,'Parent',ax2,'Color','k') <--- This line works
plot(ax2, x2, y2) <--- This line doesn't work
I've looked the plot documentation 2-D line plot but cannot seem to get plot(ax,__) to help/do what I expect.
The figure ends up not plotting the second plot and the axes end up overlapping.
Any suggestions how to fix this and get 2 axes plotting to work?
I'm currently using MATLAB R2014b.
Finally figured this one out after trying to think about MATLAB's hierarchy of setting things.
The plot seems to reset the axis ax2 properties so setting them before plot doesn't make a difference. line doesn't do this it seems. So to get this to work with plots I did the following:
clear all; close all; clc;
% Arbitrary x's and y's
x1 = [10 20 30 40];
y1 = [1 2 3 4];
x2 = [100 200 300 400];
y2 = [105 95 85 75];
figure
plot(x1,y1,'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'r')
ax2 = axes('Color','none'); % Create secondary axis
plot(ax2, x2,y2,'o', 'MarkerEdgeColor', 'b', 'MarkerFaceColor', 'b')
% Now set the secondary axis attributes
ax2.Color = 'none'; % Make the chart area transparent
ax2.XAxisLocation = 'top'; % Move the secondary x axis to the top
ax2.YAxisLocation = 'right'; % Move the secondary y axis to the right

MATLAB Subplot Make Figure Larger

I am plotting two maps next to each other using subplot. However, now, the image is turning out like this:
Is there any way to make the map part of the image larger? I would like to plot the maps side by side, by in this image, the resolution is low and the size is small.
%% Graph one site at a time
nFrames = 6240; % Number of frames.
for k = 94:nFrames
h11 = subplot(1,2,1); % PM2.5
% Map of conterminous US
ax = figure(1);
set(ax, 'visible', 'off', 'units','normalized','outerposition',[0 0 1 1]);
ax = usamap('conus');
set(ax,'Position',get(h11,'Position'));
delete(h11);
states = shaperead('usastatelo', 'UseGeoCoords', true,...
'Selector',...
{#(name) ~any(strcmp(name,{'Alaska','Hawaii'})), 'Name'});
faceColors = makesymbolspec('Polygon',...
{'INDEX', [1 numel(states)], 'FaceColor', 'none'}); % NOTE - colors are random
geoshow(ax, states, 'DisplayType', 'polygon', ...
'SymbolSpec', faceColors)
framem off; gridm off; mlabel off; plabel off
hold on
% Plot data
scatterm(ax,str2double(Lat_PM25{k})', str2double(Lon_PM25{k})', 25, str2double(data_PM25{k})', 'filled');
% Colorbar
caxis([5 30]);
h = colorbar;
ylabel(h,'ug/m3');
% Title
title(['PM2.5 24-hr Concentration ', datestr(cell2mat(date_PM25(k)), 'mmm dd yyyy')]);
%%%%
h22 = subplot(1,2,2); % O3
% Map of conterminous US
ax2 = usamap('conus');
set(ax2,'Position',get(h22,'Position'));
delete(h22);
states = shaperead('usastatelo', 'UseGeoCoords', true,...
'Selector',...
{#(name) ~any(strcmp(name,{'Alaska','Hawaii'})), 'Name'});
faceColors = makesymbolspec('Polygon',...
{'INDEX', [1 numel(states)], 'FaceColor', 'none'}); % NOTE - colors are random
geoshow(ax2, states, 'DisplayType', 'polygon', ...
'SymbolSpec', faceColors)
framem off; gridm off; mlabel off; plabel off
hold on
% Plot data
scatterm(ax2,str2double(Lat_O3{k})', str2double(Lon_O3{k})', 25, str2double(data_O3{k})'*1000, 'filled');
hold on
% Colorbar
caxis([10 90]);
h = colorbar;
ylabel(h,'ppb');
% Title
title(['O3 MDA8 Concentration ', datestr(cell2mat(date_O3(k)), 'mmm dd yyyy')]); % Title changes every daytitle(str);
% Capture the frame
mov(k) = getframe(gcf); % Makes figure window pop up
% Save as jpg
eval(['print -djpeg map_US_' datestr(cell2mat(date_PM25(k)),'yyyy_mm_dd') '_PM25_24hr_O3_MDA8.jpg']);
clf
end
close(gcf)
To change the amount of space the data occupies in the figure, you can use this command:
set(gca,'Position',[0.1 .1 0.75 0.85])
You'll have to play with the numbers a bit, to get things look nice. Note that Matlab rescales everything when you resize the figure window, so the optimal numbers depend on the window size you want to use.
On the other hand, you want to make the map bigger in comparison to the colorbar. You cannot make it without changing your window size, because your maps are already as high as the color bars. I would suggest to:
Set caxis to the same range in both plots.
Remove the colorbar on the left one.
Increase the height of your figure window to make the maps occupy as much width as possible.
Put the two images nicelye side by side using the command above.
For more information, see Matlab Documentation on Axes Properties.
Example:
% Default dimenstions
figure
x = 1:.1:4;
y = x;
[X, Y] = meshgrid(x,y);
subplot(1,2,1)
h = pcolor(X, Y, sin(X).*cos(Y)*2);
set(h, 'EdgeAlpha', 0);
axis square
colorbar
subplot(1,2,2)
h = pcolor(X, Y, sin(Y).*cos(X));
set(h, 'EdgeAlpha', 0);
axis square
colorbar
% adjust dimensions
subplot(1,2,1)
set(gca, 'Position', [0.1 0.1 0.3 0.85])
subplot(1,2,2)
set(gca, 'Position', [0.55 0.1 0.3 0.85])
This blog post has many great examples of FileExchange scripts dealing with size of subplots.
subplot_tight works very well and makes the subplots larger. Instead of writing in subplot(1,2,1), use subplot_tight(1,2,1)
My problem was similar -> scaling subplots in a figure a bit more up. Important for me though, was to maintain the aspect ratio that I've set before.
Enhancing the answer from #texnic in order to not have to set the values manually, one might use the following:
scale = 1.1; % Subplot scale
subplot(1,2,1)
% Your plotting here ...
pos = get(gca, 'Position'); % Get positions of the subplot [left bottom width height]
set(gca, 'Position', [pos(1) pos(2) pos(3)*scale pos(4)*scale]); % Scale width and height
Understanding this, one can also easily implement a parametric move of the subplot.

axes labels not displaying on 3d subplots

I have created 5 3D subplots which include a for loop. However, the labels of the X and Y axes are not displaying for some reason. I would appreciate any help on this matter. Below is the code.
On a separate note, any suggestions to make the figure more aesthetically pleasing would also be much appreciated.
% parameters
b=0.5;
O=27;
x=1:1:5;
% energies
e1 = 1:1:100;
e2 = 1:1:100;
% function
[e1,e2]=meshgrid(e1,e2);
hb=#(x)((O.^2)./factorial(O-x)).*...
exp(-b.*O.*e2);
hu=#(x)(O.^x).*...
exp(-b.*O.*e1);
p=#(x)hb(x)./(hb(x)+hu(x));
f=figure('visible','on')
clf(f);
for i=x
subplot(2,3,i);
mesh(e1,e2,p(i))
title(['X = ',int2str(i)], 'FontSize',12);
% log all axes
set(gca, 'XScale', 'log');
set(gca, 'YScale', 'log');
set(gca, 'ZScale', 'log');
axis([1 100 1 100 10^-300 1])
axis square
grid off
set(gca,'FontSize',10)
xlabel('e1')
ylabel('e2')
zlabel('p_{H}')
end
The issue seems to be something internal to MATLAB with how it is setting the position of the x and y labels when a 3D surface plot is used. This doesn't happen with a basic plot3 plot. If you do a get(get(gca,'Xlabel','Position')), you see that the z coordinate of the label is set to infinity, which I would guess is the problem.
I've come up with a less than ideal workaround, but it seems to accomplish the task:
% parameters
b=0.5;
O=27;
x=1:1:5;
% energies
e1 = 1:1:100;
e2 = 1:1:100;
% function
[e1,e2]=meshgrid(e1,e2);
hb=#(x)((O.^2)./factorial(O-x)).*...
exp(-b.*O.*e2);
hu=#(x)(O.^x).*...
exp(-b.*O.*e1);
p=#(x)hb(x)./(hb(x)+hu(x));
f=figure('visible','on');
clf(f);
for i=x
subplot(2,3,i);
mesh(e1,e2,p(i))
title(['X = ',int2str(i)], 'FontSize',12);
% log all axes
set(gca, 'XScale', 'log');
set(gca, 'YScale', 'log');
set(gca, 'ZScale', 'log');
axis([1 100 1 100 10^-300 1])
axis square
grid off
set(gca,'FontSize',10)
xlabel('e1')
ylabel('e2')
zlabel('p_{H}')
set(get(gca,'xlabel'),'Units','Normalized','Position',[0.75 0 0])
set(get(gca,'ylabel'),'Units','Normalized','Position',[0 0.05 0])
end
You'll probably have to manipulate those position vectors to get the labels exactly where you'd like.
I would also submit a bug report and see what MathWorks says.

plot in all the subplots at the same time

I have a figure with 2 subplots.
I would like to know if it's possible (and how) to draw the same plots in all the subplots at the same time.
For example in the following plot I'd like to plot (x,y) simultaneously and then proceed separately.
fig1 = figure
subplot(2,1,1)
plot(x,y)
hold on
subplot(2,1,2)
plot(x,y)
hold on
subplot(2,1,1)
plot(x,z)
subplot(2,1,2)
plot(x,k)
You can do it with set using cell arrays as follows. See the documentation for details.
subplot(2,1,1);
h1 = plot(x,y); %// get a handle to the plot
subplot(2,1,2)
h2 = plot(x,y); %// get a handle to the plot
set([h1; h2], {'xdata'}, {x1; x2}, {'ydata'}, {y1; y2})
%// new values: x1 x2 y1 y2
If you're asking because you want to plot the same plot behind say 16 subplots, then you could do it in a loop:
for k= 1:16
s(k) = subplot(4,4,k);
plot(x,y);
hold on;
end
If you just want it for 2 subplots then there is nothing wrong with your current code

Plot outside axis in Matlab

How to plot something outside the axis with MATLAB? I had like to plot something similar to this figure;
Thank you.
Here is one possible trick by using two axes:
%# plot data as usual
x = randn(1000,1);
[count bin] = hist(x,50);
figure, bar(bin,count,'hist')
hAx1 = gca;
%# create a second axis as copy of first (without its content),
%# reduce its size, and set limits accordingly
hAx2 = copyobj(hAx1,gcf);
set(hAx2, 'Position',get(hAx1,'Position').*[1 1 1 0.9], ...
'XLimMode','manual', 'YLimMode','manual', ...
'YLim',get(hAx1,'YLim').*[1 0.9])
delete(get(hAx2,'Children'))
%# hide first axis, and adjust Z-order
axis(hAx1,'off')
uistack(hAx1,'top')
%# add title and labels
title(hAx2,'Title')
xlabel(hAx2, 'Frequency'), ylabel(hAx2, 'Mag')
and here is the plot before and after:
You can display one axis with the scale you want, then plot your data on another axis which is invisible and large enough to hold the data you need:
f = figure;
% some fake data
x = 0:20;
y = 23-x;
a_max = 20;
b_max = 23;
a_height = .7;
%% axes you'll see
a = axes('Position', [.1 .1 .8 a_height]);
xlim([0 20]);
ylim([0 20]);
%% axes you'll use
scale = b_max/a_max;
a2 = axes('Position', [.1 .1 .8 scale*a_height]);
p = plot(x, y);
xlim([0 20]);
ylim([0 b_max]);
set(a2, 'Color', 'none', 'Visible', 'off');
I had similar problem and I've solved it thanks to this answer. In case of bar series the code is as follows:
[a,b] = hist(randn(1000,1)); % generate random data and histogram
h = bar(b,a); % plot bar series
ylim([0 70]) % set limits
set(get(h,'children'),'clipping','off')% turn off clippings