Plot line colors and legend colors don't match

460 visualizaciones (últimos 30 días)
Robert Whitlock
Robert Whitlock el 4 de Sept. de 2018
Editada: Robert Whitlock el 9 de Sept. de 2018
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 comentarios
Stephen23
Stephen23 el 5 de Sept. de 2018
Editada: Stephen23 el 5 de Sept. de 2018
"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 el 9 de Sept. de 2018
Editada: Robert Whitlock el 9 de Sept. de 2018
hold on was being used. Thank you for letting me know about other ways I could achieve the effect I was looking for.

Iniciar sesión para comentar.

Respuesta aceptada

jonas
jonas el 4 de Sept. de 2018
Editada: jonas el 4 de Sept. de 2018
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 comentarios
jonas
jonas el 5 de Sept. de 2018
Editada: jonas el 5 de Sept. de 2018
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 el 9 de Sept. de 2018
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!

Iniciar sesión para comentar.

Más respuestas (0)

Etiquetas

Productos


Versión

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by