plot based on a value
2 次查看(过去 30 天)
显示 更早的评论
MattC
2023-3-9
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?
采纳的回答
Voss
2023-3-9
编辑:Voss
2023-3-9
% 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 个评论
MattC
2023-3-9
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
2023-3-9
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
2023-3-9
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)
Voss
2023-3-9
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
2023-3-9
编辑:MattC
2023-3-9
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
2023-3-9
Maybe an error occurred, maybe somewhere before "yl = yline(limit, '--r', 'LineWidth',1);".
Check your command window for error messages.
MattC
2023-3-9
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
2023-3-9
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
2023-3-9
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
2023-3-9
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
2023-3-9
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
2023-3-9
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
2023-3-15
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
2023-3-15
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
2023-3-15
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
2023-3-15
% 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
2023-3-15
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
2023-3-15
If you want each plot to follow the same coloring scheme, yes, just use the same code for each plot.
MattC
2023-3-15
Okay so apart from implementing the logic multiple times there isn't any workaround?
Voss
2023-3-15
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
2023-3-15
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
2023-3-16
编辑:MattC
2023-3-16
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
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Graphics Object Programming 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- 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)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)