multiple plot in one plot in MATLAB using hold on/off statements - matlab

How can I fix this so that it would show all three plots in one plot?
I followed the instruction in this SO answer but didn't work out: https://stackoverflow.com/a/8773571/2414957
figure;
t = -pi:0.01:pi;
a = sin(t);
plot(t, a, 'r', 'DisplayName', 'a'); hold on;
fhat = (21./(8*pi.^10))*(33*pi.^4-3465*pi.^2+31185)*t.^2 +(3750*pi.^4 -30*pi.^6 -34650*pi.^2)*t.^3 +(5*pi^8-765*pi.^6+7425*pi.^4)*t;
plot(t, fhat, 'c', 'DisplayName', 'fhat');
hold on;
p = t - (t.^3)/factorial(3) + (t.^5)/factorial(5);
plot(t, p, 'b', 'DisplayName', 'p');
hold on;
title('Sine plot by sin(t)');
xlabel('t');
ylabel('sin(t)');
legend('show');

The 3 plots have variant range, therefore, you need to make normalization to plot all functions on the same space
figure;
t = -pi:0.01:pi;
a = sin(t);p = t - (t.^3)/factorial(3) + (t.^5)/factorial(5);
fhat = (21./(8*pi.^10))*(33*pi.^4-3465*pi.^2+31185)*t.^2 +(3750*pi.^4 -30*pi.^6 -34650*pi.^2)*t.^3 +(5*pi^8-765*pi.^6+7425*pi.^4)*t;
%display
plot(t, p/norm(p), 'b', 'DisplayName', 'p');
hold on; %you need only one 'hold on'
plot(t, a/norm(a), 'r', 'DisplayName', 'a');
plot(t, fhat/norm(fhat), 'c', 'DisplayName', 'fhat');
title('Sine plot by sin(t)');
xlabel('t');
ylabel('sin(t)');
legend('show');

You are plotting all three functions. What happens is that p is drawn over a. They are both very small compared to that, and therefore fall on the same pixels on your screen.
To verify this you can zoom in:
set(gca,'ylim',[-1.5,1.5])
Alternatively, plot p using dots or dashes, so the other line shows through in between:
figure;
t = -pi:0.01:pi;
a = sin(t);
plot(t, a, 'r', 'DisplayName', 'a'); hold on;
fhat = (21./(8*pi.^10))*(33*pi.^4-3465*pi.^2+31185)*t.^2 +(3750*pi.^4 -30*pi.^6 -34650*pi.^2)*t.^3 +(5*pi^8-765*pi.^6+7425*pi.^4)*t;
plot(t, fhat, 'c', 'DisplayName', 'fhat');
hold on;
p = t - (t.^3)/factorial(3) + (t.^5)/factorial(5);
plot(t, p, 'b--', 'DisplayName', 'p'); % Note the 'b--' line format here!
hold on;
title('Sine plot by sin(t)');
xlabel('t');
ylabel('sin(t)');
legend('show');

Related

'hold on' not working for Multi-position subplot in matlab

I am animating some subplots in MATLAB (R2015a). However, when I attempted to position a subplot to take up multiple positions the hold on command no longer works.
Here is a simplified form of my problem:
clear
N = 20;
Analysis(:,1) = linspace(1,N,N);
Analysis(:,2:5) = randi([1, 20],20,4);
for n = 1:N;
subplot(2,2,[1,2]);
title('Particle counts at step number');
plot(Analysis(n,1), Analysis(n,2), '.', 'Markersize', 8, 'color', 'red'), hold on;
plot(Analysis(n,1), Analysis(n,3), '.', 'Markersize', 8, 'color', '[0,0.5,0]');
legend({'Methane','Oxygen'},'FontSize',8,'FontWeight','bold', 'Location', 'northeastoutside');
xlim([0,N]);
ylim([0, 20]);
subplot(2,2,[3,4]);
title('Temperature(k) and Pressure');
plot(Analysis(n,1), Analysis(n,4), '.', 'Markersize', 8, 'color', 'red'), hold on;
plot(Analysis(n,1), Analysis(n,5), '.', 'Markersize', 8, 'color', 'blue');
legend({'Temperature','Pressure'},'FontSize',8,'FontWeight','bold', 'Location', 'northeastoutside');
xlim([0,N]);
ylim([0, 20]);
pause(0.1);
drawnow;
end
The hold on command appears to work again when i remove the legend or change the position of the subplot to be singular but i need it to work with both.
As I said above, this does appear to be a bug. One possible workaround is to modify the XData and YData properties of your line objects:
For example:
N = 20;
Analysis(:,1) = linspace(1,N,N);
Analysis(:,2:5) = randi([1, 20],20,4);
subplot(2,2,[1,2]);
title('Particle counts at step number');
hold on;
ph(1) = plot(Analysis(1,1), Analysis(1,2), '.', 'Markersize', 8, 'color', 'red');
ph(2) = plot(Analysis(1,1), Analysis(1,3), '.', 'Markersize', 8, 'color', '[0,0.5,0]');
hold off;
legend({'Methane','Oxygen'},'FontSize',8,'FontWeight','bold', 'Location', 'northeastoutside');
xlim([0, N]);
ylim([0, 20]);
subplot(2,2,[3,4]);
title('Temperature(k) and Pressure');
hold on;
ph(3) = plot(Analysis(1,1), Analysis(1,4), '.', 'Markersize', 8, 'color', 'red');
ph(4) = plot(Analysis(1,1), Analysis(1,5), '.', 'Markersize', 8, 'color', 'blue');
hold off;
legend({'Temperature','Pressure'},'FontSize',8,'FontWeight','bold', 'Location', 'northeastoutside');
xlim([0 ,N]);
ylim([0, 20]);
for n = 2:N;
k = 2;
for ii = 1:4
ph(ii).XData = Analysis(1:n, 1);
ph(ii).YData = Analysis(1:n, k);
k = k + 1;
end
pause(0.1);
drawnow;
end
I believe this gives you what you're looking for. Not the prettiest but it's functional.

Is that possible to assemble several options and pass to the plot function in matlab

I am using MATLAB to plot several figures and hope these figure use the same plot options, it looks something like this:
N = 20;
Fs = 200;
t = (0:N-1)/Fs;
x = sin(2*pi*10*t);
y = cos(2*pi*20*t);
z = x + y;
figure(1),clf;
subplot(311);
plot(t, x, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
grid on;
subplot(312);
plot(t, y, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
grid on;
subplot(313);
plot(t, z, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
grid on;
You can see the plot options are exactly the same. If I want to change the style, I have to change each of them. Is that possible assemble/group them together and pass them to the plot function?
I have tried to put them in a cell like this
plotOptions = {'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3};
It doesn't work. The reason might be the plot functions would take the plotOptions as one paramter and thus failed to parse it.
Using a cell with the options was already a good approach. Just use {:}, as below:
opt = {'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3};
figure(1),clf;
subplot(311);
plot(t, x, opt{:});
Then, each element of the cell is evaluated as single argument.
Solution with unique plotting function:
subplot(312);
myplot(t,y)
Save myplot function as a separate m-file.
function myplot(t,x)
plot(t, x, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
end
The cell answer is good, another option is to set the arg value to be a variable:
faceColor = 'b';
lineWidth = 3;
figure(1),clf;
subplot(311);
plot(t, x, 'bs-', 'MarkerFaceColor', faceColor, 'LineWidth', lineWidth);
subplot(312);
plot(t, y, 'bs-', 'MarkerFaceColor', faceColor, 'LineWidth', lineWidth);
subplot(313);
plot(t, z, 'bs-', 'MarkerFaceColor', faceColor, 'LineWidth', lineWidth);
A very clean alternative approach would be to keep the plot command as simple as possible and manipulate the handles afterwards.
opts = {'Color','red','MarkerFaceColor', 'b', 'LineWidth',3};
h(1) = plot(t, x);
grid on;
subplot(312);
h(2) = plot(t, y);
grid on;
subplot(313);
h(3) = plot(t, z);
grid on;
arrayfun(#(x) set(x,opts{:}),h)
The advantage over the indeed neat approach by Nemesis is, that in case you have multiple sets of properties, like:
opts.slimRed = {'Color','red','MarkerFaceColor', 'b', 'LineWidth',1};
opts.fatBlue = {'Color','blue','MarkerFaceColor', 'b', 'LineWidth',5};
and you want to exchange them, you just need to modify one variable
arrayfun(#(x) set(x,opts.fatBlue{:}),h)
to change the appearance of a whole set of handles h.

How can I make a contour plot doesn't overlap on the line plot in one axes?

I've made 2 plot in one axes using pushbutton in matlab guide, the first plot is line plot
here is the plot
http://i1275.photobucket.com/albums/y443/Kaito_Aokage/Capture2_zpsbc76be37.png?t=1403148417
code for line plot
% X
for i = 1.5:7;
cur_x = i * 3.8;
line([cur_x, cur_x], [0 5], 'color', 'r', 'LineWidth', 1.5);
drawnow;
end;
% Y
for i = 2:7;
cur_y = i * 4;
line([0 4],[cur_y, cur_y], 'color', 'r', 'LineWidth', 1.5);
drawnow;
end;
% X2
for i = 1.5:7;
cur_x2 = i * 3.8;
line([cur_x2, cur_x2], [25 31], 'color', 'r', 'LineWidth', 1.5);
drawnow;
end;
% Y2
for i = 1:8;
cur_y2 = i * 3.5;
line([26 31],[cur_y2, cur_y2], 'color', 'r', 'LineWidth', 1.5);
drawnow;
end;
% X
line( [5.7 cur_x], [5 5], 'color', 'r', 'LineWidth', 1.5);
% Y
line( [4 4], [8 cur_y], 'color', 'r', 'LineWidth', 1.5);
% X2
line( [5.6 cur_x2], [25 25], 'color', 'r', 'LineWidth', 1.5);
% Y2
line( [26 26], [3.5 cur_y2], 'color', 'r', 'LineWidth', 1.5);
handles.axes2;
grid on;
hold on;
axis([0 30 0 30]);
and the second plot is contour plot
http://i1275.photobucket.com/albums/y443/Kaito_Aokage/Capture3_zpsfd46dedf.png?t=1403148576
code for contour plot
xMove = 3;
yMove = 10;
r = 30;
rx = -r:0.1:r;
ry = r:-0.1:-r;
[x_coor, y_coor] = meshgrid(rx, ry);
radius = sqrt(x_coor.^2+y_coor.^2);
contourf(x_coor + xMove, y_coor + yMove, radius,'edgecolor','none');
xlabel('Widht');
ylabel('Long');
axis([0 30 0 30]);
colorbar;
caxis([0 10]);
grid on;
handles.axes2;
set(gca,'layer','top');
hold on;
Pushbutton Floor is line plot and Pushbutton AP1 is contour plot. When i try to push plot contour button after line plot button, the line plot overlap by contour plot. I want line plot doesn't overlap by contour plot so the line plot can be seen after i push contour plot button. I already try holdor set(gca,'layer','top)but its not working. what should i do?
in what order are you executing the above codes ? I first executed second code then the first code and this is my output
Here is the whole code I executed, I had to remove the line handle.axis2; as it was throwing an error.( I am using matlab 2011)
close all
xMove = 3;
yMove = 10;
r = 30;
rx = -r:0.1:r;
ry = r:-0.1:-r;
[x_coor, y_coor] = meshgrid(rx, ry);
radius = sqrt(x_coor.^2+y_coor.^2);
contourf(x_coor + xMove, y_coor + yMove, radius,'edgecolor','none');
xlabel('Widht');
ylabel('Long');
axis([0 30 0 30]);
colorbar;
caxis([0 10]);
grid on;
set(gca,'layer','top');
hold on;
% X
for i = 1.5:7;
cur_x = i * 3.8;
line([cur_x, cur_x], [0 5], 'color', 'r', 'LineWidth', 1.5);
drawnow;
end;
% Y
for i = 2:7;
cur_y = i * 4;
line([0 4],[cur_y, cur_y], 'color', 'r', 'LineWidth', 1.5);
drawnow;
end;
% X2
for i = 1.5:7;
cur_x2 = i * 3.8;
line([cur_x2, cur_x2], [25 31], 'color', 'r', 'LineWidth', 1.5);
drawnow;
end;
% Y2
for i = 1:8;
cur_y2 = i * 3.5;
line([26 31],[cur_y2, cur_y2], 'color', 'r', 'LineWidth', 1.5);
drawnow;
end;
% X
line( [5.7 cur_x], [5 5], 'color', 'r', 'LineWidth', 1.5);
% Y
line( [4 4], [8 cur_y], 'color', 'r', 'LineWidth', 1.5);
% X2
line( [5.6 cur_x2], [25 25], 'color', 'r', 'LineWidth', 1.5);
% Y2
line( [26 26], [3.5 cur_y2], 'color', 'r', 'LineWidth', 1.5);
grid on;
axis([0 30 0 30]);
hold off;

mark point on figure

From this Matlab code :
a=[1:.001:5] ;
f=(1./a)-(a-1) ;
plot(a,f)
I want to mark the point when (f==0) on the figure, assuming the value of a is unknown and I should take it from the figure.
I want it to look like this:
Use the command 'text' http://www.mathworks.com/help/matlab/ref/text.html as follows,
[~,idx] = find(abs(f)<1e-3);
text( a(idx(1)), f(idx(1)), 'here we touch/cut/cross x-axis')
You can use interp1 to find the point where f = 0;
a_for_f_equal_zero = interp1(f, a, 0);
line(a_for_f_equal_zero, 0, 'marker', 'o', 'color', 'r', 'linestyle', 'none')
x_lim = get(gca, 'XLim');
y_lim = get(gca, 'YLim');
line(a_for_f_equal_zero * [1,1], [y_lim(1), 0], 'color', 'k') % vertical line
line([x_lim(1), a_for_f_equal_zero], [0,0], 'color', 'k') % horizontal line

Matlab: Adding third dimenstion to 2D plot

I have the following code to generate me a 2D plot or 2 normal distributions:
res = zeros(2, 320);
index = 1:320;
% assign some data to the res array and then approximate:
PD = fitdist(index','normal', 'frequency', res(1,:)')
pdfNormal = normpdf(index',PD.mu,PD.sigma);
plot(index', pdfNormal, 'Color', 'r', 'LineWidth', 2);
hold on;
PD = fitdist(index','normal', 'frequency', res(2,:)')
pdfNormal = normpdf(index',PD.mu,PD.sigma);
plot(index', pdfNormal, 'Color', 'b', 'LineWidth', 2);
This code generates me then the following picture:
Now I am wondering how I could add a third dimension to this plot? Essentially,
I would like to plot another 2 normal distributions, but this time in the Z-axis,
ie., in the third dimension.
Anyone an idea how I could do that easily?
Thanks so much!
If I understood correctly, you can simply give the plots different z-values. Example:
%# some random data
x = 1:300;
y = zeros(5,300);
for i=1:5
y(i,:) = normpdf(x,100+i*20,10);
end
%# plot
hold on
clr = lines(5);
h = zeros(5,1);
for i=1:5
h(i) = plot(x, y(i,:), 'Color',clr(i,:), 'LineWidth',2);
set(h(i), 'ZData',ones(size(x))*i)
end
zlim([0 6]), box on, grid on
view(3)
hold off