Hi, I would like to plot a scatter plot for 3 variables in a single plot
A = 0.5; B = 0.2; C = 1.2;
scatter('X1',A,'*'); %if a<=1 then blue color else orange
scatter('X1',B,'s'); %if b<=1 then blue color else orange
scatter('X1',C,'+'); %if c<=1 then blue color else orange
yl = yline(1, '--r', 'LineWidth',1);
I want to add a legend as well which would show these values. How to achieve this?

 Respuesta aceptada

Voss
Voss el 9 de Mzo. de 2023
Editada: Voss el 9 de Mzo. de 2023
% random vectors (10x1) of values between 0 and 2
AA = 2*rand(10,1);
BB = 2*rand(10,1);
CC = 2*rand(10,1);
DD = 2*rand(10,1);
EE = 2*rand(10,1);
limit = 1;
X = 1:10;
figure()
hold on
obj = [];
% use logical indexing to separate AA<=1 (blue) from AA>1 (orange)
idx = AA<=1;
obj(end+1) = scatter(X(idx),AA(idx),[],'b','*');
scatter(X(~idx),AA(~idx),[],[1 0.5 0],'*');
% use logical indexing to separate BB<=1 (blue) from BB>1 (orange)
idx = BB<=1;
obj(end+1) = scatter(X(idx),BB(idx),[],'b','s');
scatter(X(~idx),BB(~idx),[],[1 0.5 0],'s');
% use logical indexing to separate CC<=1 (blue) from CC>1 (orange)
idx = CC<=1;
obj(end+1) = scatter(X(idx),CC(idx),[],'b','+');
scatter(X(~idx),CC(~idx),[],[1 0.5 0],'+');
names = {'A','B','C'};
ylims = ylim();
ylims(1) = min(-1,ylims(1));
ylim(ylims);
idx = DD < EE;
if any(idx)
obj(end+1) = plot(X(idx),-1*ones(1,nnz(idx)),'s', ...
'MarkerFaceColor',[0.5 0.5 0.5],'MarkerEdgeColor','none');
names{end+1} = 'D<E';
end
if any(~idx)
idx2 = any([AA BB CC] > limit, 2);
if any(~idx & idx2)
obj(end+1) = plot(X(~idx & idx2),-1*ones(1,nnz(~idx & idx2)),'s', ...
'MarkerFaceColor','r','MarkerEdgeColor','none');
names{end+1} = 'A,B,C>1';
end
if any(~idx & ~idx2)
obj(end+1) = plot(X(~idx & ~idx2),-1*ones(1,nnz(~idx & ~idx2)),'s', ...
'MarkerFaceColor','g','MarkerEdgeColor','none');
names{end+1} = 'A,B,C<=1';
end
end
yl = yline(limit, '--r', 'LineWidth',1);
names{end+1} = 'limit';
legend([obj yl],names)
A = 0.5; B = 0.2; C = 1.2;
title(sprintf('Plot: A=%g, B=%g, C=%g',A,B,C))

30 comentarios

MattC
MattC el 9 de Mzo. de 2023
Is there a way to add the variables names and custom text to legend and title?
Example:
A = 0.5; B = 0.2; C = 1.2;
Legend('*','A','s','B','+','C','--',Limit) %Trying to show the shape in blue color with the value it belongs to A,B,C with ---in red for limit
Title ('Plot',A,B,C,'values plotted here')% Apart from plot adding the actual values for A,B,C
This gives error
Voss
Voss el 9 de Mzo. de 2023
@MattC: I've made the requested changes to the answer.
MattC
MattC el 9 de Mzo. de 2023
Perfect thank you @Voss. An additional question: So if my A,B,C variables are 50X1 double variable but having distinct values. How can we get these values in the title then?
A(50x1 double) = all values 0.5
B(50x1 double) = all values 0.2
C(50x1 double) = all values 1.2
I do not want to hardcode them to another variable because I want to keep my code generic but while printing the title I want to print only the distinct value of each A,B,C
If it's always the case that all elements of A are the same, all elements of B are the same, and all elements of C are the same, i.e., that each contains only one unique value, then:
A = 0.5*ones(50,1); % all elements the same
B = 0.2*ones(50,1);
C = 1.2*ones(50,1);
figure
title(sprintf('Plot: A=%g, B=%g, C=%g',A(1),B(1),C(1)))
If A, B, and/or C could have multiple unique values in it and you want to show all of them, then maybe something like:
A = [0.5*ones(49,1); 0.6]; % two unique elements in A
B = 0.2*ones(50,1); % one in B
C = [1.2*ones(40,1); 1.4*ones(5,1); 1.7*ones(5,1)]; % three in C
strA = sprintf('%g,',unique(A));
strB = sprintf('%g,',unique(B));
strC = sprintf('%g,',unique(C));
strA(end) = [];
strB(end) = [];
strC(end) = [];
figure
title(sprintf('Plot: A=[%s], B=[%s], C=[%s]',strA,strB,strC))
MattC
MattC el 9 de Mzo. de 2023
Editada: MattC el 9 de Mzo. de 2023
Okay so is there a way to do it without mentioning the size like (50,1) and values 0.1 etc because that would not remain constant always can be greater can be less and values can change. But will always have unique values for sure
Voss
Voss el 9 de Mzo. de 2023
That's just for demonstration, i.e., I have to create some A, B, C vectors to show that the method works. In reality, you can just apply it to your A, B, C.
MattC
MattC el 9 de Mzo. de 2023
Editada: MattC el 9 de Mzo. de 2023
Gotcha, thanks for the explanation. I am trying to incorporate one more thing here:
  • Extending the lower limit of y axis = -1 and that I am marking as green, red or grey squares on the x axis based on 3 conditions mentioned below:
  • The table from which I am using is of size (100x5) which has 2 columns across which I am making a comparison first and then the values:
  • If column D < column E then mark x where y=-1 as grey
  • If column D >= column E then make additional check if any of A,B,C pointer above 1(limit), then mark x where y=-1 as red
  • If column D >= column E then make additional check if any of A,B,C pointer not above 1(limit), then mark x where y=-1 as green
  • Trying to add the red,green,grey squares to legend as well
Example:
Voss
Voss el 9 de Mzo. de 2023
@MattC: I've made the requested changes to the answer.
MattC
MattC el 9 de Mzo. de 2023
Thanks again @Voss. I am finding one error here. My y axis is limited to only 0.5 now I do not see the red line for 1 or any values above 0.5 in the plot. Why would that be?
Voss
Voss el 9 de Mzo. de 2023
Maybe an error occurred, maybe somewhere before "yl = yline(limit, '--r', 'LineWidth',1);".
Check your command window for error messages.
MattC
MattC el 9 de Mzo. de 2023
The code runs fine without any errors it's just that it does not show y=1 maybe because of this code? Not sure though
ylims = ylim();
ylims(1) = min(-1,ylims(1));
ylim(ylims);
Voss
Voss el 9 de Mzo. de 2023
That part is setting the lower y-limit to -1 (or something less than -1 if it already was less than -1), but it won't work if you have a variable called ylim.
Do you have a variable called ylim?
What happens if you comment out those three lines?
MattC
MattC el 9 de Mzo. de 2023
I think then it worked just fine like before. Thanks for catching that @Voss
Does matlab allow to plot data across 2 y axis?
Example values:
A here is in different units(secs) and B,C in different units(cms) so I want the data for them to be on different y axis but in the same figure with different shapes
A = 0.5; B = 200; C = 400;
MattC
MattC el 9 de Mzo. de 2023
Thanks for the reference and help :)
MattC
MattC el 9 de Mzo. de 2023
I am not sure what I am doing wrong here but it shows some random lines and not shapes like I am trying. Can you please help?
A = 2*rand(10,1);
B = 20*rand(10,1);
C = 30*rand(10,1);
grid on
box on
hold on
x = 1:10;
y = A;
yyaxis left
plot(x,y)
z = [B C];
yyaxis right
plot(x,z)
It shows random lines because the data (A, B, C) is random (i.e., from rand).
To have shapes, use markers:
A = 2*rand(10,1);
B = 20*rand(10,1);
C = 30*rand(10,1);
grid on
box on
hold on
x = 1:10;
y = A;
yyaxis left
plot(x,y,'*')
z = [B C];
yyaxis right
plot(x,z,'s')
MattC
MattC el 9 de Mzo. de 2023
Yeah I think so but there is another error when I try to add different shapes to A,B,C and legend
plot(xaxis,y,'p')
plot(x,z,'^','o')
MattC
MattC el 15 de Mzo. de 2023
Hey @Voss, since you helped me with this problem before. I am trying to make some changes to this plot now:
  1. Getting away from the y=-1 axis, setting a limit as y=0 (which means removing the points on that axis as well)
  2. Conditions still are the same but instead of adding a separate color coding on the y=-1 axis I am now trying to color all A,B,C in those colors based on the conditions (moving away from blue and orange) based on the limit at y=1 (Example: if the condition for D<E is satisfied then color A,B,C all in grey instead of the earlier implementation where y=-1 being grey and A,B,C having color (blue,orange) based on above or below y=1)
Can you please help if this is possible?
Something like this?
% random vectors (10x1) of values between 0 and 2
AA = 2*rand(10,1);
BB = 2*rand(10,1);
CC = 2*rand(10,1);
DD = 2*rand(10,1);
EE = 2*rand(10,1);
limit = 1;
X = 1:10;
figure()
hold on
obj = [];
names = {};
color1 = [0.5 0.5 0.5];
color2 = [1 0.5 1];
idx = DD < EE;
if any(idx)
obj(end+1) = plot(X(idx),AA(idx),'*', ...
'MarkerFaceColor',color1,'MarkerEdgeColor',color1);
obj(end+1) = plot(X(idx),BB(idx),'s', ...
'MarkerFaceColor',color1,'MarkerEdgeColor',color1);
obj(end+1) = plot(X(idx),CC(idx),'+', ...
'MarkerFaceColor',color1,'MarkerEdgeColor',color1);
names(end+[1 2 3]) = {'A (D<E)','B (D<E)','C (D<E)'};
end
if any(~idx)
obj(end+1) = plot(X(~idx),AA(~idx),'*', ...
'MarkerFaceColor',color2,'MarkerEdgeColor',color2);
obj(end+1) = plot(X(~idx),BB(~idx),'s', ...
'MarkerFaceColor',color2,'MarkerEdgeColor',color2);
obj(end+1) = plot(X(~idx),CC(~idx),'+', ...
'MarkerFaceColor',color2,'MarkerEdgeColor',color2);
names(end+[1 2 3]) = {'A (D>=E)','B (D>=E)','C (D>=E)'};
end
obj(end+1) = yline(limit, '--r', 'LineWidth',1);
names{end+1} = 'limit';
ylims = ylim();
ylims(1) = min(0,ylims(1));
ylim(ylims);
legend(obj,names)
MattC
MattC el 15 de Mzo. de 2023
Sorry, for the confusion, here is what I mean:
Same conditions:
  • If column D < column E then mark all points A,B,C in grey
  • If column D >= column E then make additional check if any of A,B,C pointer above 1(limit), then mark all A,B,C as red
  • If column D >= column E then make additional check if any of A,B,C pointer not above 1(limit), then mark A,B,C as green
I think the logic to check conditions still remains same but just that instead of adding the color on y=-1 I am now trying to change the color for A,B,C itself and all of them to be red,green,grey based on the check
idx = DD < EE;
if any(idx)
obj(end+1) = plot(X(idx),-1*ones(1,nnz(idx)),'s', ...
'MarkerFaceColor',[0.5 0.5 0.5],'MarkerEdgeColor','none');
names{end+1} = 'D<E';
end
if any(~idx)
idx2 = any([AA BB CC] > limit, 2);
if any(~idx & idx2)
obj(end+1) = plot(X(~idx & idx2),-1*ones(1,nnz(~idx & idx2)),'s', ...
'MarkerFaceColor','r','MarkerEdgeColor','none');
names{end+1} = 'A,B,C>1';
end
if any(~idx & ~idx2)
obj(end+1) = plot(X(~idx & ~idx2),-1*ones(1,nnz(~idx & ~idx2)),'s', ...
'MarkerFaceColor','g','MarkerEdgeColor','none');
names{end+1} = 'A,B,C<=1';
end
end
yl = yline(limit, '--r', 'LineWidth',1);
names{end+1} = 'limit';
% random vectors (10x1) of values between 0 and 2
AA = 2*rand(10,1);
BB = 2*rand(10,1);
CC = 2*rand(10,1);
DD = 2*rand(10,1);
EE = 2*rand(10,1);
limit = 1;
X = 1:numel(AA);
figure()
hold on
obj = [];
names = {};
idx = DD < EE;
if any(idx)
obj(end+1) = plot(X(idx),AA(idx),'*', ...
'MarkerFaceColor',[0.5 0.5 0.5],'MarkerEdgeColor',[0.5 0.5 0.5]);
names{end+1} = 'A (D<E)';
obj(end+1) = plot(X(idx),BB(idx),'s', ...
'MarkerFaceColor',[0.5 0.5 0.5],'MarkerEdgeColor',[0.5 0.5 0.5]);
names{end+1} = 'B (D<E)';
obj(end+1) = plot(X(idx),CC(idx),'+', ...
'MarkerFaceColor',[0.5 0.5 0.5],'MarkerEdgeColor',[0.5 0.5 0.5]);
names{end+1} = 'C (D<E)';
end
if any(~idx)
idx2 = any([AA BB CC] > limit, 2);
if any(~idx & idx2)
obj(end+1) = plot(X(~idx & idx2),AA(~idx & idx2),'*', ...
'MarkerFaceColor','r','MarkerEdgeColor','r');
names{end+1} = 'A (D>=E)';
obj(end+1) = plot(X(~idx & idx2),BB(~idx & idx2),'s', ...
'MarkerFaceColor','r','MarkerEdgeColor','r');
names{end+1} = 'B (D>=E)';
obj(end+1) = plot(X(~idx & idx2),CC(~idx & idx2),'+', ...
'MarkerFaceColor','r','MarkerEdgeColor','r');
names{end+1} = 'C (D>=E)';
end
if any(~idx & ~idx2)
obj(end+1) = plot(X(~idx & ~idx2),AA(~idx & ~idx2),'*', ...
'MarkerFaceColor','g','MarkerEdgeColor','g');
names{end+1} = 'A (D>=E)';
obj(end+1) = plot(X(~idx & ~idx2),BB(~idx & ~idx2),'s', ...
'MarkerFaceColor','g','MarkerEdgeColor','g');
names{end+1} = 'B (D>=E)';
obj(end+1) = plot(X(~idx & ~idx2),CC(~idx & ~idx2),'+', ...
'MarkerFaceColor','g','MarkerEdgeColor','g');
names{end+1} = 'C (D>=E)';
end
end
yl = yline(limit, '--r', 'LineWidth',1);
names{end+1} = 'limit';
legend([obj yl],names)
ylims = ylim();
ylims(1) = min(0,ylims(1));
ylim(ylims);
MattC
MattC el 15 de Mzo. de 2023
That worked, thank you so much. Can I maintain the same color coding scheme for A,B,C for other plots as well?
Example: I have 2 plots:
  1. The above plot is let's say plot 1
  2. There is a plot 2 with same x axis as plot 1
grid on
box on
hold on
x = 1:numel(AA);
y = BB;
yyaxis left
plot(x,y,'*')
z = [CC DD];
yyaxis right
plot(x,z,'s')
If for example when x axis=1 all A,B,C are red then I want them (A,B,C) to be red for x axis=1 for plot2 as well
Voss
Voss el 15 de Mzo. de 2023
If you want each plot to follow the same coloring scheme, yes, just use the same code for each plot.
MattC
MattC el 15 de Mzo. de 2023
Okay so apart from implementing the logic multiple times there isn't any workaround?
Voss
Voss el 15 de Mzo. de 2023
If you mean some way for the second plot to automatically use the same colors as the first plot, or something like that, no, I don't think so.
But you can put the code/logic into a function and call it for each plot, so you're implmenting it once and using it multiple times.
MattC
MattC el 15 de Mzo. de 2023
Okay will that then. Also, I added this question: https://www.mathworks.com/matlabcentral/answers/1929395-multiple-subplots-having-same-legend which is basically to check if there is way I can remove the individual legends and have a common legend for all my plots in center above. Do you know if this is possible?
MattC
MattC el 16 de Mzo. de 2023
Editada: MattC el 16 de Mzo. de 2023
Hey @Voss, editing my previous comment. After I get this Co value from the function I am not sure how to use it in plots like:
%% dual y axis plot
plot(x,AA,'sCo',x,BB,'+Co')
%% single plot
plot(x,BB,'pCo')
%%% Gives an error: Invalid color or line style.
%% function
function Co = getc(AA,BB,CC,DD,EE)
limit = 1;
idx = DD < EE;
idx2 = any([AA BB CC] > limit, 2);
Co = [];
if any(idx)
Co =[0.5 0.5 0.5];
end
if any(~idx)
if any(~idx & idx2)
Co = 'r';
end
if any(~idx & ~idx2)
Co ='g';
end
end
end
Voss
Voss el 16 de Mzo. de 2023
plot(x,AA,'s',x,BB,'+','Color',Co)
plot(x,BB,'p','Color',Co)
MattC
MattC el 22 de Mzo. de 2023
Hey @Voss, I think this is not picking the right Co value from the function it picks the grey color anyways. I am not sure what's incorrect with the function. Can you please help?

Iniciar sesión para comentar.

Más respuestas (0)

Productos

Etiquetas

Preguntada:

el 9 de Mzo. de 2023

Comentada:

el 22 de Mzo. de 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by