You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
plot based on a value
2 views (last 30 days)
Show older comments
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?
Accepted Answer
Voss
on 9 Mar 2023
Edited: Voss
on 9 Mar 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 Comments
MattC
on 9 Mar 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
MattC
on 9 Mar 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
Voss
on 9 Mar 2023
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)))
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1319500/image.png)
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))
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1319505/image.png)
MattC
on 9 Mar 2023
Edited: MattC
on 9 Mar 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
MattC
on 9 Mar 2023
Edited: MattC
on 9 Mar 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:
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1319565/image.png)
Voss
on 9 Mar 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
on 9 Mar 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
on 9 Mar 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)
Voss
on 9 Mar 2023
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')
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1319680/image.png)
MattC
on 15 Mar 2023
Hey @Voss, since you helped me with this problem before. I am trying to make some changes to this plot now:
- Getting away from the y=-1 axis, setting a limit as y=0 (which means removing the points on that axis as well)
- 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?
Voss
on 15 Mar 2023
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)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1325325/image.png)
MattC
on 15 Mar 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';
Voss
on 15 Mar 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: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);
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1325365/image.png)
MattC
on 15 Mar 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:
- The above plot is let's say plot 1
- 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
on 15 Mar 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
on 15 Mar 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
on 16 Mar 2023
Edited: MattC
on 16 Mar 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
More Answers (0)
See Also
Categories
Find more on Graphics Object Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)