Two point series on the same graph on MatLab - matlab

I want to draw two separated lines, but I get the two lines on two points. How do I draw them separated?
When you implement the code, the green line should start from point 3 and end in point 4 on the x-tick. But, it starts again from point 1 and end in point2.
%% My question code:
a=3; %point1
b=4; %point2
c=6; %point3
d=7; %point4
plot([a b], 'k- *');
hold on;
plot([c d], 'g- *');
hold off
set(gca, 'XTick', 1:4, 'XTickLabel', {'point1', 'point2', 'point3','point4'})
axis([0 10 0 10]);

When you hold the current plot and plot a new one. x axis values are taken as if it is the first plot. To avoid the confusion, specify values for both x and y axes.
So change your plot commands like this:
plot([1,2], [a,b], 'k- *');
hold on;
plot([3,4], [c,d], 'g- *');
hold off;
or combine two plot commands into a single one like this:
plot([1,2], [a,b], 'k- *', [3,4], [c,d], 'g- *');

Related

matlab adding single legend for multiple data

figure(1);
hold on;
na=4;
circle_X = [0 0 5 5]';
circle_Y = [0 3 0 3]';
for a = 1:na
r=0.3;
N=100;
theta=linspace(0, 2*pi, N);
cx=r*cos(theta)+circle_X(a);
cy=r*sin(theta)+circle_Y(a);
plot3(cx , cy, 300*ones(N), 'r', 'linewidth', 2,'DisplayName',sprintf('circle'));
end
legend('show');
I want to draw 4 circles and add a single legend 'circle' indicating 4 circles all at once, without using "legend('circle')".
For now the legend looks like this
how should I change the code?
First, you don't need plot3, you can achieve the same figure with plot, and probably the long legend is because of that.
just change the line of plot to that:
plot(cx , cy, 'r', 'linewidth', 2,'DisplayName','circle');
Now, the legend will have 4 entries because you draw four objects. If you want a single entry you have some ways:
add the legend inside the loop, after an if statement. For example,
if a==1 ,
legend('show');
end
get handles for your plots, and legend just one of them. It can be done directly from legend, but then you will need to specify the string:
for....
h(a)=plot...
end
legend(h(1),'circle')
get handles like in part 2, and if you don't want specify the string 'circle', you can use the undocumented hasbehavior:
for...
h(a)=plot...
end
hasbehavior(h(2),'legend',false);
hasbehavior(h(3),'legend',false);
hasbehavior(h(4),'legend',false);
l=legend('show');

Looping through columns to make subplots

I have an spectral absorbance matrix in xls format which has column 1 as wavelength, and columns 2:3 as the associated absorbance spectra for particles from depth1 in water column. 2:3 are duplicates so they have to be plotted together. Next i have columns 4:5 as once again duplicate absorbance spectra for particles from depth2 in water column. Then data for depth3, depth4 etc. The matrix is 1001 rows by 13 columns.
I would like have 3 subplots (depth1, depth2 and depth3) in one figure with each subplot holding the 2 duplicate spectra of each depth.
I tried to follow the excellent responses to this question but this gives me one line per subplot but i want to plot two lines (duplicate spectra). So I did the following and it works but I can only get 3 subplots:
[num,txt,raw]=xlsread('ANACONDAS2010-ST1.xls');
legendCell=cellstr(txt);
figure
subplot(3,1,1)
plot(num(:,1), num(:,2:3),'r');grid on; box on; xlabel('Wavelength'), ylabel('Absorbance'),legend(legendCell(2:3)),legend boxoff
subplot(3,1,2)
plot(num(:,1), num(:,4:5),'b');grid on; box on; xlabel('Wavelength'), ylabel('Absorbance'),legend(legendCell(4:5)), legend boxoff
subplot(3,1,3)
plot(num(:,1), num(:,6:7),'g');grid on; box on; xlabel('Wavelength'), ylabel('Absorbance'),legend(legendCell(6:7)), legend boxoff
title('STATION 1','fontweight','bold','fontsize',16);
But as you can see this gives me only 1 figure with 3 subplots and the rest od the depths (d4, d5, d6) remain unplotted as i havent been able to specifiy them,
Because my script is long and cumbersome I would have liked to run this through a loop but I couldn't figure out how to do it in spite of battling with the code provided in the 2nd answer which I kind of understood unlike the first one.
Updated answer
Inserted version V2 of the code
Version V2 of the code allows displaying unlimited pairs of data, also it is even simpler than V1.
% Generation of example data
num=1:33;
number_of_data_colums=14;
num=[num' rand(length(num),number_of_data_colums)];
% Generation of legend string
for i=1:number_of_data_colums
legendCell{i}=['Absor. ' num2str(i)];
end
% Get the size of data to be plotted (columns from 2 to ...)
[r,c]=size(num);
n_data=floor((c-1)/2);
% Define the number of data to be plotted in each subplt
data_x_plot=2;
% Consistency check: if the number of column data is not even generate an
% error message and exit
if(n_data*2 ~= (c-1))
error('Number of data columns is not even')
else
% Define the number of subplot of each figure
n_sub_plot=3;
% Subplot and figure counters
s_plot_cnt=1;
fig_cnt=1;
% Create the first figure
figure
% External loop on figures
for i=2:2:n_data*2
% If three subplot have been added to a figure, open a new figure
if(s_plot_cnt == 4)
% The Title is assigne to the first subplot of each figure
title(ax(fig_cnt,1),['STATION ' num2str(fig_cnt)],'fontweight','bold','fontsize',16);
s_plot_cnt=1;
fig_cnt=fig_cnt+1;
figure
end
ax(fig_cnt,s_plot_cnt)=subplot(n_sub_plot,1,s_plot_cnt);
% The indices of columns to be plotted are computed automatically
plot(num(:,1), num(:,i:i+1));
grid on;
box on;
xlabel('Wavelength')
ylabel('Absorbance')
% add legend
legend(legendCell(i-1:i),-1)
% Increment subplot's counter
s_plot_cnt=s_plot_cnt+1;
% legend boxoff
end
end
% Add the last title
title(ax(fig_cnt,1),['STATION ' num2str(fig_cnt)],'fontweight','bold','fontsize',16);
Previous answer and
Version V1 of the code
I'm not sure I've understood your question, nevertheless, if you have 6 pairs of data and you want 3 subplot, you need 2 figures.
I've modified your original script in order to automatically determine the number of figure you need, generate the subplots and plot 2 set of data in each of them.
Updated code - now with legends
% Generation of example data
num=1:33;
num=[num' rand(length(num),12)];
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% UPDATED CODE STARS HERE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Generation of legend string
legendCell{1}='Wavel';
for i=2:13
legendCell{i}=['Absor. ' num2str(i)];
end
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% UPDATED CODE ENDS HERE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Get the size of data to be plotted
[r,c]=size(num);
% Define the number of data to be plotted in each subplt
data_x_plot=2;
% Define the number of subplot of each figure
n_sub_plot=3;
% Evaluate the number of figures to be created
n_fig=(c-1)/(data_x_plot*n_sub_plot);
% Define the index of data columns
idx=[2:2:c-1];
idx=reshape(idx,n_sub_plot,data_x_plot)';
% External loop on figures
for i=1:n_fig
figure
% Internal loop on subplots
for j=1:n_sub_plot
% The subplot indices are computed automatically
ax(i,j)=subplot(n_sub_plot,1,j);
% The indices of columns to be plotted are computed automatically
plot(num(:,1), num(:,idx(i,j):idx(i,j)+1));
grid on;
box on;
xlabel('Wavelength')
ylabel('Absorbance')
% add legend
legend(legendCell(idx(i,j):idx(i,j)+1),-1)
% legend boxoff
end
% The Title is assigne to the first subplot of each figure
title(ax(i,1),['STATION ' num2str(i)],'fontweight','bold','fontsize',16);
end
Given a set of 12 columns of data, this is the output:
Updated graphs, with legends
Maybe you should use Hold to retain current plot when adding new plots.
So your code should be like this:
[num,txt,raw]=xlsread('ANACONDAS2010-ST1.xls');
legendCell=cellstr(txt);
figure
subplot(3,1,1)
plot(num(:,1), num(:,2),'r');grid on;
hold on;
plot(num(:,1), num(:,3),'m');
box on; xlabel('Wavelength'), ylabel('Absorbance'),legend(legendCell(2:3)),legend boxoff
subplot(3,1,2)
plot(num(:,1), num(:,4),'b');
hold on;
plot(num(:,1), num(:,5),'c');
grid on; box on; xlabel('Wavelength'), ylabel('Absorbance'),legend(legendCell(4:5)), legend boxoff
subplot(3,1,3)
plot(num(:,1), num(:,6),'g');
hold on;
plot(num(:,1), num(:,7),'k');
grid on; box on; xlabel('Wavelength'), ylabel('Absorbance'),legend(legendCell(6:7)), legend boxoff
title('STATION 1','fontweight','bold','fontsize',16);

Matlab - Legend does not match my graph

I am having trouble matching my graph with my axis. The first two plots work and the second two do not. I am trying to plot Temperature versus Pressure for two Argo floats and then Salinity versus Pressure. Here is my code:
% First Plot
subplot(221);
plot(float1winter.T,float1winter.P,'b');
hold on;
plot(float1summer.T,float1summer.P,'r');
hold on;
tempAdiff = abs(float1summer.T-float1winter.T)
plot(tempAdiff,float1summer.P,'--k');
hold on;
set(gca,'ydir','reverse');
title('Argo Float #1901440 Temp Profiles');
legend(['float1winter','float1summer','tempAdiff'],{'11-29-2013','07-01-2013','Temperature Difference'},'location','southwest');
xlabel('Temperature (°C)');
ylabel('Pressure');
shg;
% Second Plot
subplot(222);
plot(float2winter.S,float2winter.P,'m');
hold on;
plot(float2summer.S,float2summer.P,'c');
hold on;
set(gca,'ydir','reverse');
title('Argo Float #1901440 Salinity Profiles');
legend(['float2winter','float2summer'],{'11-29-2013','06-02-2013'},'location','southwest');
xlabel('Salinity (psu)');
ylabel('Presure');
shg;
% Third Plot
subplot(223);
% Matrix demensions did not agree bewteen winter and summer profiles. The summer profile was 71 x 2 and the winter was 70 x 2. I tried "reshape"
% and that didn't work. So I changed the vector of float3summer.T to
% float3bsummer.T with an array of 70 x 2
float3bsummer.T = float3summer.T(1:70,1:2);
float3bsummer.P = float3summer.P(1:70,1:2);
plot(float3winter.T,float3winter.P,'Linewidth',1,'color','blue');
hold on;
plot(float3bsummer.T,float3bsummer.P,'Linewidth',1,'color','red');
hold on;
tempdiff = abs(float3bsummer.T-float3winter.T)
plot(tempdiff,float3bsummer.P,'--k');
hold on;
set(gca,'ydir','reverse'); % this line reverses the y-axis so that depth increases downward
title('Argo Float #1901415 Tempearture Profiles');
hold on;
summerfloat = plot(float3bsummer.T,float3bsummer.P,'r');
legend(['float3winter.T','summerfloat','tempdiff'],{'12-03-2013','07-03-2013','Temp Diff'},'location','southeast');
xlabel('Temperature (°C)');
ylabel('Pressure');
axis ([-1,4,0,2000]);
shg;
% Fourth Plot
subplot(224);
plot(float3winter.S,float3winter.P,'g');
% Changed matrix dimensions for Salinity of Summer
float3bsummer.S = float3summer.S(1:70,1:2);
float3bsummer.P = float3summer.P(1:70,1:2);
plot(float3bsummer.S,float3bsummer.P,'.b');
hold on;
set(gca,'ydir','reverse');
title('Argo Float #1901415 Salinity Profiles');
h4 = plot(float3winter.S,float3winter.P,'g');
hold on;
h5 = plot(float3bsummer.S,float3bsummer.P,'.b');
hold on;
legend(['float3winter','float3bsummer.T'],{'12-03-2013','07-03-2013'},'location','southwest');
xlabel('Salinity (psu)');
ylabel('Pressure');
axis ([33.8,34.8,0,2000]);
shg;
% Save File to Desktop
set(gcf,'color','w');
saveas(gcf,'~/Desktop/hw1_figure1.pdf','pdf');![enter image description here][1]
I guess that you're trying to associate the set of strings for your legend, {'11-29-2013','07-01-2013','Temperature Difference'}, with the plots made from the variables ['float1winter','float1summer','tempAdiff'].
However, this isn't how legend works. MATLAB has no way of associating the plot produced by plot(float1winter.T,float1winter.P,'b'); to the string float1winter. If you want to specify which plots go with which legend entries, you need to pass the object handles of the plots to legend, which is easiest done by returning the handles when you plot originally:
h(1) = plot(float1winter.T,float1winter.P,'b');
hold on;
h(2) = plot(float1summer.T,float1summer.P,'r');
h(3) = plot(tempAdiff,float1summer.P,'--k');
legend(h,{'11-29-2013','07-01-2013','Temperature Difference'});
Side note: you only need to call hold on once per axis - so once for each subplot but not after every plot call.
Alternatively, you can not give handles at all; legend will assign the text to the plots in the order that they were plotted:
legend({'11-29-2013','07-01-2013','Temperature Difference'})
Understanding graphics handles allows you a lot more control over plots, especially if you might want to make small adjustments to them. For example, if I decide that I want the first plot to be green rather than blue, then I can just do:
set(h(1),'Color','g');
This will change the plot color and the legend changes to match automagically. To see a list of all the properties of an object, use get with only the handle. You can set more than one property at a time. For example:
get(h(1))
set(h(1),'DisplayName','Winter','LineWidth',3,'Marker','x')

Legend containing only specific plots

I have 10 curves in a plot, but only three of them should appear in the legend. For example, among 10 curves, just the first, 5th and 10th should be in the legend, how I can do this?
Here's my program:
x=1:0.5:15;
y1=x.^1
plot(x,y1)
hold on
y2=x.^1.2
plot(x,y2)
hold on
.
.
.
y10=x.^2.2
plot(x,y10)
You can use handles for the plots, and then specify the plots for the legend by their handles:
x=1:0.5:15;
y(1,:)=x.^1;
y(2,:)=x.^1.2;
...
...
...
y(10,:)=x.^2.2;
for k=1:10
h(k)=plot(x,y(k,:));
hold on
end
legend([h(1) h(5) h(10)],'curve 1','curve 5','curve 10');
hold off
legend can take a handle or handles, and a list of strings. I've taken the liberty of rewriting your code so it plots in a loop rather than creating a bunch of y variables. Generally speaking, if you find yourself creating a series of variables named y1, y2, etc, there's a better way of doing it in MATLAB.
There are 7 plots, not 10, but you get the idea.
x=1:0.5:15;
m=1:0.2:2.2;
figure
hold on
for n = 1:7
h(n) = plot(x,x.^m(n));
end
legend(h([1,3,5]),'Plot One', 'Plot Three', 'Plot Five',...
'Location', 'NorthWest')
you need to use the plot handles in the legend function to indicate the desired curves. Inserted in your code it would look like this:
x=1:0.5:15;
y1=x.^1;
h1=plot(x,y1,'r');
hold on
y2=x.^1.2;
h2=plot(x,y2,'c');
hold on
.
.
.
y10=x.^2.2;
h10=plot(x,y10,'p');
hold off;
legend([h2,h10] , 'Fart 2', 'More Fart'); % Plot in the handle you wish
Here's a slick two-liner that I use:
a=flipud(findall(gcf,'Type','Line')); %get all line objects of current plot
legend(a([1 3]),{'a','b'}) %add legend for line 1 and 3, 'a' and 'b'
The legend command only applies to the most recent created plot, unless a handle is passed.
figure
for c=1:10
subplot(4,4,c)
ezplot('y=sin(x)');
if c==5||c==10
legend('sin(x)')
end
end

multiple colours on matlab histogram

Hi I am trying to get multiple colours on a matlab histogram - i think the following should do it:
figure
hist(ligand,50)
h=findobj(gca,'Type','patch');
set(h,'FaceColor',[0 .5 .5],'EdgeColor','w')
hold on;
hist(potassium,50)
g=findobj(gca,'Type','patch');
set(g,'FaceColor',[0 1 1],'EdgeColor','w')
hold on;
hist(rectifier,50)
title('Alignment to AFP1')
xlabel('Score'); ylabel('Number of Sequences')
hold off;
where the first colour is [0 .5 .5], the second [0 1 1] and the third is the default colour. However even though I have specified two separate colours for the first two using two handles, h and g - both are the same colour, using the g handle.
What am I doing wrong?
edit - this is for Luis Mendos's suggestion - I am getting an "index exceeds matrix dimensions" with the following
figure
hist(ligand,50)
g=findobj(gca,'Type','patch');
set(g(1),'FaceColor',[0 .5 .5],'EdgeColor','w')
hold on;
hist(potassium,50)
set(g(2),'FaceColor',[0 1 1],'EdgeColor','w')
hist(rectifier,50)
title('Alignment to AFP1')
xlabel('Score'); ylabel('Number of Sequences')
hold off;
Thanks.
The problem is that g is a two-element vector, because it includes the two histograms that have already been plotted. Remove the lines with h (lines 3 and 4) and replace the line set(g,...) by
set(g(1),'FaceColor',[0 .5 .5],'EdgeColor','w')
set(g(2),'FaceColor',[0 1 1],'EdgeColor','w')