What is the Best Way to Deal with an Empty Line Object?

12 visualizaciones (últimos 30 días)
Paul
Paul el 13 de Jun. de 2021
Comentada: Paul el 13 de Jun. de 2021
Suppose I have some data:
x = 1:10; y = 1:10;
Now I want to plot three lines based on three logical index vectors.
i1 = x<=3;
i2 = x > 3 & x < 7;
i3 = x >= 7;
hlines = plot(x(i1),y(i1),'r',x(i2),y(i2),'b',x(i3),y(i3),'g');
legend(hlines,'first','second','third');
So far so good. Now suppose i2 is empty
i1 = x<=3;
i2 = x > 100;
i3 = x >= 7;
hlines = plot(x(i1),y(i1),'r',x(i2),y(i2),'b',x(i3),y(i3),'g');
legend(hlines,'first','second','third');
Warning: Ignoring extra legend entries.
Oops, the legend is not what I want; green should be 'third'.
One way to deal with this is to append NaN to all inputs
hlines = plot([x(i1) nan],[y(i1) nan],'r',[x(i2) nan],[y(i2) nan],'b',[x(i3) nan],[y(i3) nan],'g');
legend(hlines,'first','second','third');
I don't mind that 'second' shows up in legend, even though there is no line. In fact, that's preferred. Keep in mind that all this is in a function and there is no way to know a priori of any of i1, i2, i3 will be empty.
Is there a better way to make sure the the legend is consistent regardless of whether or not i1, i2, or i3 is empty?

Respuesta aceptada

Walter Roberson
Walter Roberson el 13 de Jun. de 2021
i1 = x<=3;
i2 = x > 100;
i3 = x >= 7;
plot(x(i1),y(i1),'r',x(i2),y(i2),'b',x(i3),y(i3),'g');
hold on
hlines = plot(nan,nan,'r', nan, nan, 'b', nan, nan, 'g');
legend(hlines, {'first', 'second', 'third'});
That is, when your legend does not necessarily match the graphic objects exactly, then create fake invisible graphic objects and legend() those.
This technique is very useful for situations such as scatter() where the number of graphics objects being created does not match the number of classes needed to be described.
  5 comentarios
Walter Roberson
Walter Roberson el 13 de Jun. de 2021
Some of the issues can be reduced by setting Tag for the objects and the same Tag for the proxy line being used for the legend.
obj1 = findobj(ax, 'Tag', 'first');
set(obj1, 'color', 'k', 'Marker', '*')
Paul
Paul el 13 de Jun. de 2021
Do you think it's worth an enhancement request for plot to not return an empty line obect for empty input argurments? Or would that be a change in behavior too much to ask for? I still wonder if there would be any drawbacks to returning a non-empty Line object (other than that users now might be relying on the current behavior in some way.

Iniciar sesión para comentar.

Más respuestas (1)

Steven Lord
Steven Lord el 13 de Jun. de 2021
x = 1:10;
y = 1:10;
i1 = x<=3;
i2 = x > 100;
i3 = x >= 7;
hold on
plot(x(i1),y(i1),'r','DisplayName', 'first');
plot(x(i2),y(i2),'b','DisplayName', 'second');
plot(x(i3),y(i3),'g','DisplayName', 'third');
legend show
  1 comentario
Walter Roberson
Walter Roberson el 13 de Jun. de 2021
This does help, but the user prefers that second also show up, even if there are no visible lines for it.

Iniciar sesión para comentar.

Categorías

Más información sobre Specifying Target for Graphics Output en Help Center y File Exchange.

Productos


Versión

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by