Plot line colors and legend colors don't match

184 次查看(过去 30 天)
When I plot these functions and make a legend, the colors for the lines don't match the colors in the legend. Also, the plot reused the same blue color (at least) twice.
% This file plots gamma as a function of v/c as well as some of its Taylor
% expansions
clear; clf;
syms gamma_voc(voc); % gamma wrt v/c
syms T0(x) T1(x) T2(x) T3(x) T4(x)
% The functions are symbolically defined so I can do symbolic operations
gamma_voc(voc) = 1./sqrt(1-voc^2);
T0(x) = ones(size(x))*1;
T1(x) = ones(size(x))*1;
T2(x) = 1+(1/2)*x^2;
T3(x) = 1+(1/2)*x^2;
T4(x) = 1+(1/2)*x^2+(1/24)*x^4;
% The symbolically defined functions can't be used numerically, so use
% these instead
gamma_voc_FUN = matlabFunction(gamma_voc);
T0_FUN = matlabFunction(T0);
T1_FUN = matlabFunction(T1);
T2_FUN = matlabFunction(T2);
T3_FUN = matlabFunction(T3);
T4_FUN = matlabFunction(T4);
% Now that we have our functions, let's plot them
grid on;
hold on;
axis([-2 2 0 4]);
daspect([1 1 1]);
lw = 5;
x = -1:0.01:1; % domain of gamma(v/c)
y = gamma_voc_FUN(x); plot(x,y,'LineWidth',lw);
x = -2:0.01:2; % Visible domain of Taylor series expansions
y = T0_FUN(x); plot(x,y,'LineWidth',lw);
y = T1_FUN(x); plot(x,y,'LineWidth',lw);
y = T2_FUN(x); plot(x,y,'LineWidth',lw);
y = T3_FUN(x); plot(x,y,'LineWidth',lw);
y = T4_FUN(x); plot(x,y,'LineWidth',lw);
legend('gamma','T0','T1','T2','T3','T4');
  2 个评论
Stephen23
Stephen23 2018-9-5
编辑:Stephen23 2018-9-5
"Also, the plot reused the same blue color (at least) twice."
Each time you call plot is independent from the other calls, and it will start the colors from the first one again. If you want to automatically cycle through the line ColorOrder colors, then you should do one of these:
  • set the axes NextPlot property to 'add'.
  • use hold on (only since MATLAB R2014b).
  • use just one plot call.
Then you will get an automatic cycling of the line colors (from the axes ColorOrder).
Robert Whitlock
Robert Whitlock 2018-9-9
编辑:Robert Whitlock 2018-9-9
hold on was being used. Thank you for letting me know about other ways I could achieve the effect I was looking for.

请先登录,再进行评论。

采纳的回答

jonas
jonas 2018-9-4
编辑:jonas 2018-9-4
This question is asked almost on a daily basis. Use plot handles as input to the legend function, and you won't have this problem.
h(1)=plot(x,y,'LineWidth',lw);
h(2)=plot(x,y,'LineWidth',lw);
...
legend(h,'gamma','T0',...);
Alternatively, use the 'DisplayName' property to store the label directly in the line handle.
h(1)=plot(x,y,'LineWidth',lw,'DisplayName','T0');
h(2)=plot(x,y,'LineWidth',lw,'DisplayName','T1');
...
legend(h)
  7 个评论
jonas
jonas 2018-9-5
编辑:jonas 2018-9-5
Thanks for showing the handles. Perhaps it would be best to remove them again, as the long list makes it kind of hard to follow the discussion.
Let me try explaining what's going on. If you want to plot a single line, then the two input variables x and y should generally have the same size. If they do not have the same size, then usually you get an error.
There is however a special case when you have a vector x of size (1 x n) and one matrix y of size (m x n). In this case, plot will plot every row m against the vector x, as they match in length. In your case, you have a vector x of size (1 x n) and a scalar y of size (1 x 1). This means that you get n number of plots, which are really only single points.
For example, consider this code:
h=plot([1 2],1)
h =
2×1 Line array:
Line
Line
As you can see, you get two line handles as output because y is scalar and x is a vector. In your case, you get the same number of handles as the number of elements in your x-vector. These handles are first in the uistack, so they show up first in the legend.
How to solve?
Make sure your vector x always matches your vector y in size when you plot. In this case, I suspect that the error is in one of your custom functions. Make sure they output a vector and not a scalar, even when y is constant. You can also concatenate your vectors in a single matrix. In doing so, you will also ensure that they have the correct length, as the code will otherwise crash. Avoid producing 800 useless line handles, as this will surely mess up your legend and increase the run-time significantly.
Robert Whitlock
Robert Whitlock 2018-9-9
Thank you, that explains why it was acting that way!
I also got a reply from another Matlab source (from a bug report) that suggested using @(x)(subs(T0(x)) instead of matlabFunction(T0). This also clears up the problem, and has the advantage that I don't have to explicitly define the symbolically defined T0(x) to have a certain number of rows and columns.
Thanks!

请先登录,再进行评论。

更多回答(0 个)

产品


版本

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by