single legend entry for all lines of plotted array?
34 views (last 30 days)
Show older comments
Here is what I am trying to do: I have a matrix of spectra (wpsec.spec, ns x nv where ns=number of spectra) and would like to plot as two different types of lines along with a few other lines of information.
> plot(1:nv,wspec.spec(gout,:),'b',1:nv,wspec.spec(~gout,:),':k',1:nv,cent,'g',1:nv,low,'r',1:nv,up,'r');
plots all the spectra identified by logical index "gout" as blue lines ('b') and all other spectra as dotted black lines (':k') along with a green line for "cent" (1 x nv), and red lines for "low" and "up" (both 1 x nv). This works ok to produce the plot. Now I want to add a legend with 4 entries ("outliers","normal","central value" and "thresholds") as
> legend('outliers','normal','central value','thresholds')
Of course this doesn't work -- it will just put the labels on the first 5 blue lines of "wspec.spec(gout,:)" , assuming that nnz(gout)>5. What is needed is to "group" all the blue lines under a single legend entry. But you cannot just:
> p(1) = plot(1:nv,wspec.spec(~gout,:),'b','DisplayName','outliers');
since we get an error "Subscripted assignment dimension mismatch." as it wants to apply 'DisplayName' to all nnz(gout) blue lines. It would be nice if the 'DisplayName' property had this flexibility to automatically expand 'outliers' to apply to all the lines...sigh.
So, what is the best way to accomplish what I want? I know I could plot just the first line of each multiline array, generate the legend, and then plot the remaining lines of each array:
> p(1) = plot(1:nv,wspec.spec(find(gout,1,'first'),:),'b','DisplayName','outliers');
> hold on;
> p(2) = plot(1:nv,wspec.spec(find(~gout,1,'first'),:),':k','DisplayName','normal');
> p(3) = plot(1:nv,cent,'g','DisplayName','Central Value');
> p(4) = plot(1:nv,low,'r','DisplayName','Threshold');
> p(5) = plot(1:nv,up,'r');
> p(6) = plot(1:nv,wspec.spec(~gout,:),':k'); %results in duplicate plotting of first line
> p(7) = plot(1:nv,wspec.spec(gout,:),'b'); %results in duplicate plotting of first line
> hold off;
> legend(p(1:4));
but this seems un-tidy and has other problems with layering lines on top of other lines depending on the order in the plot commands. With all the changes in the graphics engine structure, I am wondering if there isn't already a way to associate legend entries to a "container" of plot lines.
3 Comments
Accepted Answer
Star Strider
on 27 Jan 2018
I cannot run your code. Since you have 'DisplayName' defined in every plot call:
p(1) = plot(1:nv,wspec.spec(~gout,:),'b','DisplayName','outliers');
you most likely need only to use the 'show' argument in your legend call:
legend('show')
See if that works.
6 Comments
Star Strider
on 27 Jan 2018
As always, my pleasure.
‘I am guessing that when we index into the plot handle [i.e., h1(1) or h2(1)] we are accessing the individual Line handles?’
You are guessing correctly. In my ‘Another Option’ code, you will see that ‘h1’ and ‘h2’ are handles to several (in my code, 5) line objects. Using them without the subscript in the legend call produces the result you don’t want. Choosing only one produces the result you want.
The documentation for the line handles is in the legend section on Specify Charts to Include in Legend (link).
With respect to HG2, one source is Graphics Changes in R2014b (link). There are more discussions on the Graphics (link) page.
More Answers (0)
See Also
Categories
Find more on Data Distribution Plots 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!