I have figures from three different codes in matlab, with the same axis.
How do I combine them in to one plot?
Is there a way to write a new script and reference a plot from another code?
Thanks
Consider the following three functions p1(), p2() and p3() which plot three different waveforms. Each function returns three handles for figure, plot and axes, respectively.
function [fig,plt, ax] = p1()
fig = figure;
t = linspace(0, 2*pi, 500);
plt = plot(t, sin(2*pi*2*t));
xlim([0 2*pi])
grid on
ax = gca;
end
function [fig, plt, ax] = p2()
fig = figure;
t = linspace(0, 2*pi, 500);
plt = plot(t, cos(2*pi*0.5*t));
xlim([0 2*pi])
grid on
ax = gca;
end
function [fig, plt, ax] = p3()
fig = figure;
t = linspace(0, 2*pi, 500);
plt = plot(t, 2*exp(-0.5*t));
xlim([0 2*pi])
grid on
ax = gca;
end
These three functions create the following figures:
Then, by copying the Children attribute from each axes to a subplot handle on a new figure, you can merge the three independently generated graphs into one figure, as follows:
clear
close all
[f1, p1, ax1] = p1();
[f2, p2, ax2] = p2();
[f3, p3, ax3] = p3();
merge = figure;
sb1 = subplot(3,1,1);
copyobj(ax1.Children, sb1);
grid on
sb2 = subplot(3,1,2);
copyobj(ax2.Children, sb2);
grid on
sb3 = subplot(3,1,3);
copyobj(ax3.Children, sb3);
grid on
Outputting the following figure:
This is just a crude approach, however, it should give you a starting point.
Just to clarify, the fig and plt handles are only passed as an output in case you need to use their attributes.
Play around with this code and let me know if it works for you
Related
I'm plotting several confusion matrices using plot_confusion() function and I want to put them in a subplot (2x5 figures), but it does not seem to work.It displays every confusion matrix separately. Are there any restriction for plotting confusion? Thanks!
figure
Subplot(2,1,1);
plotconfusion(targets,outputs,'train');
subplot(2,1,2);
plotconfusion(targets1,outputs1,'test')
You're "not supposed" to do that (the functionality is not included), but you can trick Matlab a little, because at the end of a day it's just an axes object:
%% First Example Data
[x,t] = cancer_dataset;
net = patternnet(10);
net = train(net,x,t);
y = net(x);
%// plot
plotconfusion(t,y)
%// get handle and enable second plöt
cp1 = gcf;
cp1.NextPlot = 'new'
ax1 = findobj(cp1,'Type','Axes')
%% Second Example Data
[x,t] = cancer_dataset;
net = patternnet(5);
net = train(net,2*x,t);
y = net(x);
%// plot
plotconfusion(t,y)
%// get handle and enable third plöt
cp2 = gcf;
cp2.NextPlot = 'new'
ax2 = findobj(cp2,'Type','Axes')
%% combine plots
f1 = figure(42)
f1s1 = subplot(121)
copyobj(allchild(ax1),f1s1)
f1s2 = subplot(122)
copyobj(allchild(ax2),f1s2)
You loose the labels and titles and may need to adjust the axis, but I guess you're able to do that.
I can't find any info on how to do this on the Internet other than to use plotyy which only seems to work for two functions.
From Matlab documentation:
Use Right y-Axis for Two Data Sets
Plot three data sets using a graph with two y-axes. Plot one set of
data associated with the left y-axis. Plot two sets of data associated
with the right y-axis by using two-column matrices.
x = linspace(0,10);
y1 = 200*exp(-0.05*x).*sin(x);
y2 = 0.8*exp(-0.5*x).*sin(10*x);
y3 = 0.2*exp(-0.5*x).*sin(10*x);
plotyy(x,y1,[x',x'],[y2',y3']);
In my opinion, the way to do this that confers the most manual control is to create three overlapping axes with the plots you need, and only display the axis for the topmost one. You could even create 'empty' axes just so you they can serve as the only axis with defined 'limits' in the x and y axes.
Example:
ax1 = axes();
X1 = linspace(0,8*pi, 100); Y1 = sin(X1);
plot(X1, Y1, 'r', 'linewidth', 10);
ax2 = axes();
h = ezplot(#(x) x .* sin(x), [-100, 100]); set(h, 'color', 'w');
ax3 = axes();
image()
%% place them on top of each other by calling them in the order you want
axes(ax3); % bottommost
axes(ax1);
axes(ax2); % topmost
set(ax1, 'visible', 'off');
set(ax2, 'visible', 'off');
set(ax3, 'visible', 'on'); % this is the axes who's limits will show
I have to plot 1 line plot and 3 grouped scatter plots in a single plot window.
The following is the code I tried,
figure;
t1=0:0.1:10;
X = 2*sin(t1);
ts = 0:1:10;
Y1 = randi([0 1],length(ts),1);
Y2 = randi([0 1],length(ts),1);
Y3 = randi([0 1],length(ts),1);
plotyy(t1,X,[ts',ts',ts'],[Y1,Y2,Y3],'plot','scatter');
%plotyy(t1,X,[ts',ts',ts'],[Y1,Y2,Y3],'plot','plot');
The following are my questions,
The above code works if I replace 'scatter' by 'plot' (see commented out line), but 'scatter' works only for 1 data set and not for 3. Why?
How to individually assign colors to the 3 grouped scatter plots or plots?
Read the error message you're given:
Error using scatter (line 44) X and Y must be vectors of the same
length.
If you look at the documentation for scatter you'll see that the inputs must be vectors and you're attempting to pass arrays.
One option is to stack the vectors:
plotyy(t1,X,[ts';ts';ts'],[Y1;Y2;Y3],'plot','scatter');
But I don't know if this is what you're looking for, it certainly doesn't look like the commented line. You'll have to clarify what you want the final plot to look like.
As for the second question, I would honestly recommend not using plotyy. I may be biased but I've found it far to finicky for my tastes. The method I like to use is to stack multiple axes and plot to each one. This gives me full control over all of my graphics objects and plots.
For example:
t1=0:0.1:10;
X = 2*sin(t1);
ts = 0:1:10;
Y1 = randi([0 1],length(ts),1);
Y2 = randi([0 1],length(ts),1);
Y3 = randi([0 1],length(ts),1);
% Create axes & store handles
h.myfig = figure;
h.ax1 = axes('Parent', h.myfig, 'Box', 'off');
h.ax2 = axes('Parent', h.myfig, 'Position', h.ax1.Position, 'Color', 'none', 'YAxisLocation', 'Right');
% Preserve axes formatting
hold(h.ax1, 'on');
hold(h.ax2, 'on');
% Plot data
h.plot(1) = plot(h.ax1, t1, X);
h.scatter(1) = scatter(h.ax2, ts', Y1);
h.scatter(2) = scatter(h.ax2, ts', Y2);
h.scatter(3) = scatter(h.ax2, ts', Y3);
Gives you:
And now you have full control over all of the axes and line properties. Note that this assumes you have R2014b or newer in order to use the dot notation for accessing the Position property of h.ax1. If you are running an older version you can use get(h.ax1, 'Position') instead.
I'm new to MATLAB, and I've been searching around for what I'm trying to do, but the results don't fit quite well.
I'm graphing plots of variations of transfer functions, the code I've done is below:
omega = 3;
K = omega * omega;
for zeta = 0.1:0.1:2
sys = tf(K,[1 2*zeta*omega omega]);
figure();
subplot(1,2,1);
step(sys);
title('Step response');
[num,den] = tfdata(sys, 'v');
disp(den);
r = roots(den);
subplot(1,2,2);
%hold (subplot(1,2,2), 'on');
plot(real(r), imag(r), 'o');
title('Pole Locations in Complex Plane');
end
Each time the loop runs, it will create a new figure. The first subplot should be unique for every figure, but the second subplot should plot the accumulation of all points (roots of denominator of all transfer functions) from figures before it. I tried to use hold (subplot(1,2,2), 'on'); to keep the second subplot, but it didn't work. My thought is that because the subplots are different figures, hold on cannot be used.
How can I solve this problem? Any help will be great.
A solution is to use 'Tag' in your subplot. I am using your code to edit:
omega = 3;
K = omega * omega;
for zeta = 0.1:0.1:2
sys = tf(K,[1 2*zeta*omega omega]);
figure();
sb = subplot(1,2,1);
set(sb, 'Tag', 'daddy') % Something to tag with - memorable
step(sys);
title('Step response');
[num,den] = tfdata(sys, 'v');
disp(den);
r = roots(den);
sb = subplot(1,2,2);
set(sb, 'Tag', 'child')
sb = findobj('Tag','child'); % Use MATLAB methods to find your tagged obj
set(sb,'NextPlot','add'); % set 'NextPlot' property to 'add'
plot(real(r), imag(r), 'o');
title('Pole Locations in Complex Plane');
end
DOes this work for you? btw. This is also in MATLAB central. You should use that too.
As the title says, I'm trying to save the 2-variable slices of a mesh function (as a .jpg, for example) as a subplot. I want to do this using a .m file because I have many plots to generate. I have figured out how to plot the views on their own figures, but I cannot get them to plot properly as subplots within a figure. To illustrate what I mean:
Here are the outputs on individual plots:
3D mesh: 3D MATLAB mesh plot
XY view: XY MATLAB mesh view
YZ view: YZ MATLAB mesh view
XZ view: XZ MATLAB mesh view
And here is my plotting code (not working):
%Ambiguity Surface
fid = figure(fnum);
axes1 = axes('Parent',fid);
view(axes1,[-62.5 28]);
grid(axes1,'on');
hold(axes1,'all');
msh = mesh(taux,fdy,z,'Parent',axes1);
xlabel ('Delay - seconds');
ylabel ('Doppler - Hz');
zlabel ('Ambiguity function (Normalized Magnitude-Squared)');
fname = strcat(name,' (Ambiguity Function z(\tau;F_d))');
title(fname);
cb = colorbar('peer',axes1);
set(get(cb,'ylabel'),'String','Magnitude-Squared (dB)');
hold off;
printFig(fid,fnum,sname)
fnum = fnum + 1;
%Ambiguity Slices
fid = figure(fnum);
hold all;
subplot(2,1,1);
axes1 = axes();
grid(axes1,'on');
view(axes1,[90 0]);
msh = mesh(taux,fdy,z);
xlabel ('Delay - seconds','Visible','off');
ylabel ('Doppler - Hz');
zlabel ('Ambiguity function (Normalized Magnitude-Squared)','Visible','off');
fname = strcat(name,' (Ambiguity Function Slice z(\tau;F_d) # \tau = 128)');
title(fname)
subplot(2,1,2);
axes2 = axes();
grid(axes2,'on');
view(axes2,[0 0]);
msh = mesh(taux,fdy,z);
xlabel ('Delay - seconds','Visible','off');
ylabel ('Doppler - Hz','Visible','off');
zlabel ('Ambiguity function (Normalized Magnitude-Squared)','Visible','off');
cb = colorbar('peer',axes2);
set(get(cb,'ylabel'),'String','Magnitude-Squared');
fname = strcat(name,' (Ambiguity Function Slice z(\tau;F_d) # F_d = 0)');
title(fname)
hold off;
printFig(fid,fnum,slname)
fnum = fnum+1;
printFig() just sets up directory info and does print command.
My code sets up the two subplots and then overlays a full 3-d view of the mesh plot, which is not what I want. I'd like to see two of the views (XZ and YZ) on a single figure.
Thanks for the help!
-Dylan
EDIT:
Per #Andrew_L's suggestion, I modified this in my code:
sp1 = subplot(2,1,1);
axes(sp1);
axes1 = axes();
grid(axes1,'on');
view(axes1,[90 0]);
msh = mesh(taux,fdy,z,'Parent',axes1);
This is repeated for the other subplot. The result is still the same, however. It appears to set up the two blank subplots properly and then display the full pseudo-3D plot over it.
Here is a stripped example very similar to what you are trying to achieve:
%# create axes, and set the view of each
hAx(1) = subplot(221); h = mesh(peaks); view(3)
hAx(2) = subplot(222); copyobj(h,hAx(2)); view(0,90), title('X-Y')
hAx(3) = subplot(223); copyobj(h,hAx(3)); view(0,0) , title('X-Z')
hAx(4) = subplot(224); copyobj(h,hAx(4)); view(90,0), title('Y-Z')
%# set properties of axes
for i=1:4
grid(hAx(i), 'on')
axis(hAx(i), 'tight')
xlabel(hAx(i), 'Delay (sec)');
ylabel(hAx(i), 'Doppler (Hz)');
zlabel(hAx(i), 'Ambiguity function');
end
title(hAx(1), 'Short Tone Ping z(\tau;F_d)')
hc = colorbar('Peer',hAx(1));
set(get(hc,'YLabel'), 'String','Magnitude-Squared (dB)')
When you call axes1 = axes(); right below subplot(2,1,1);, you are setting axes1 to the default full-window axis when you call axes() without any arguments, which is causing the overlap. Instead, try using the handle returned by subplot to generate the axes handle. Try the following code for the second section:
%Ambiguity Slices
fid = figure(fnum);
H1 = subplot(2,1,1);
pos1 = get(H1, 'Position');
set(H1,'Position',[pos1(1) pos1(2) 0.8*pos1(3) pos1(4)]); %leave space for colorbar;
grid on;
msh = mesh(taux,fdy,z);
view([90 0]);
mapping = caxis;
xlabel ('Delay - seconds','Visible','off');
ylabel ('Doppler - Hz');
zlabel ('Ambiguity function (Normalized Magnitude-Squared)','Visible','off');
fname = strcat(name,' (Ambiguity Function Slice z(\tau;F_d) # \tau = 128)');
title(fname)
H2 = subplot(2,1,2);
pos2 = get(H2, 'Position');
set(H2,'Position',[pos2(1) pos2(2) 0.8*pos2(3) pos2(4)]); %leave space for colorbar;
grid on;
msh = mesh(taux,fdy,z);
caxis(mapping);
view([0 0]);
xlabel ('Delay - seconds','Visible','off');
ylabel ('Doppler - Hz','Visible','off');
zlabel ('Ambiguity function (Normalized Magnitude-Squared)','Visible','off');
axes('Position', [0.05 0.05 0.9 0.9], 'Visible', 'off'); %setup axes for colorbar;
caxis(mapping);
cb = colorbar();
ylabel(cb, 'Magnitude-Squared');
fname = strcat(name,' (Ambiguity Function Slice z(\tau;F_d) # F_d = 0)');
title(fname)
printFig(fid,fnum,slname)
fnum = fnum+1;
This (should) at least get everything displayed how you want - I believe that the colorbar scale will not correspond to anything in particular (most likely the number of discrete colors in the bar), so extra code is needed to make sure both plots use the same colormap, and that you change the colormap for the colorbar.