19
$\begingroup$

Update: NOT fixed in V10.0 - 12.0.0


While testing the examples from this recent post, i've noticed a problem in V.10 with PlotLegends when it has to automatically generate more than 15 labels (i.e. when there are more then 15 functions to plot). There's no problem with V.9.

The problem concerns the option values : Automatic and "Expressions". For example :

Plot[Evaluate[Range[20] + x], {x, -5, 5}, PlotLegends -> "Expressions"]

enter image description here

Plot[Evaluate[Range[20] + x], {x, -5, 5}, PlotLegends -> Automatic]

enter image description here

No problem however when you specify explicitly the labels in the legend :

Plot[Evaluate[Range[20] + x], {x, -5, 5}, PlotLegends -> Range[20]]

enter image description here

$\endgroup$
4
  • $\begingroup$ As I understand Mr.Wizard's answer, I would not consider this a bug but surmise it is a conscious, reasonable (undocumented) design decision by WRI. Have you reported it to WRI and did they have a response? $\endgroup$
    – Michael E2
    Dec 12, 2014 at 11:39
  • $\begingroup$ @MichaelE2 No, I did not and do not actually plan to report that, it' s rather a minor problem, there are simple workarounds. Since it works in version 9 and there are no obvious reason why it have to be modified, I tagged it as a "bug". If not, it should be at least tagged in some way I guess ... "undocumented change" ;) I have actually bookmarked several posts which, I think, lack at least a warning tag. I've planned to post a question about that to meta because that bug tag mechanism is not actually clear for me. $\endgroup$
    – SquareOne
    Dec 12, 2014 at 13:31
  • 1
    $\begingroup$ I do think such restrictions ought to be documented (under "Possible Issues") so that users don't waste time trying to figure out why it doesn't work. And perhaps a warning message and way to override. My preference would be the V9 way plus a warning when the number of legends exceeds the number of colors. I mention this just in case someone at WRI takes a look. :) $\endgroup$
    – Michael E2
    Dec 12, 2014 at 14:07
  • 1
    $\begingroup$ @SquareOne I removed the bugs tag according to community practice, as there is neither consensus nor confirmation (from WRI) that this is a bug. $\endgroup$
    – Mr.Wizard
    Dec 12, 2014 at 16:01

2 Answers 2

20
$\begingroup$

We may observe that the automatically generated legend limits the number of legend items to the number of available colors in the given color scheme. Using this utility function:

plot[scheme_] := Plot[Evaluate[Range[20] + x], {x, -5, 5},
   PlotLegends -> "Expressions", PlotStyle -> scheme]

Observe the result for indexed color scheme #42 which has only four colors:

plot[42]

enter image description here

There are eight in #26:

plot[26]

enter image description here

As since there are 21 in #60 all your lines have a legend:

plot[60]

enter image description here

And if you specify a gradient color scheme:

Plot[Evaluate[Range[50] + x], {x, -5, 5}, PlotLegends -> "Expressions", 
 PlotStyle -> "Rainbow"]

enter image description here

$\endgroup$
9
  • 3
    $\begingroup$ +1, well, obviously. Otherwise they aren't distinguishable. (Yes, this was a well duh moment for me.) $\endgroup$
    – rcollyer
    Nov 19, 2014 at 13:30
  • $\begingroup$ @Kuba no it doesn't. You just need a color scheme that has enough colors, otherwise the legend algorithm says it can't distinguish them. So, they're not useful. $\endgroup$
    – rcollyer
    Nov 19, 2014 at 14:03
  • 1
    $\begingroup$ @rcollyer I know :) I should have GoldenBadge "Missunderstood guy" $\endgroup$
    – Kuba
    Nov 19, 2014 at 14:05
  • 2
    $\begingroup$ 10 colors is the most common for "Indexed" colors and 21 is the maximum number of colors. Tally[Length@ColorData[#, "ColorList"] & /@ Range@Length@ColorData["Indexed"]] gives {{15, 24}, {9, 14}, {10, 48}, {11, 7}, {8, 7}, {6, 1}, {7, 1}, {4,1}, {13, 4}, {12, 2}, {21, 2}, {14, 2}} $\endgroup$
    – Bob Hanlon
    Nov 19, 2014 at 14:46
  • 1
    $\begingroup$ @Bob A shorter way to write that: Length /@ ColorData["Indexed", "ColorList"] // Tally $\endgroup$
    – Mr.Wizard
    Nov 19, 2014 at 15:03
3
$\begingroup$

You can use indexed colors as color function to generate as many distinct colors as you like. For example, although

Length @ ColorData[97, "ColorList"]

15

we can generate 100 distinct colors mapping ColorData[97] on Range[100]

ColorData[97] /@ Range[100] // CountDistinct

100

ColorData[97, "Range"]

{1, ∞, 1}

ColorData[97, "ColorFunction"]

enter image description here

ColorData[97, "ColorFunction"] // InputForm

enter image description here

A nice illustration suggested by @Mr.Wizard in comments:

ArrayPlot[Partition[ColorData[97] /@ Range[500], 21], 
 Mesh -> All, MeshStyle -> White, ImageSize -> 1 -> 30]

enter image description here

So ... if we use PlotStyle -> (ColorData[97]/@Range[20]) the issue goes away:

Plot[Evaluate[Range[20] + x], {x, -5, 5}, 
 PlotStyle -> (ColorData[97] /@ Range[20]), 
 PlotLegends -> "Expressions"]

enter image description here

and with PlotLegends -> Automatic we get

enter image description here

Note that removing the PlotStyle option or the setting PlotStyle -> 97 or PlotStyle -> ColorData[97] we get only 15 distinct colors:

colorswithdefaultplotstyle =  Cases[Plot[Evaluate[Range[20] + x], {x, -5, 5}, 
    PlotLegends -> "Expressions"], {Directive[_, col_, ___],
   _Line} :>  col, All];

{Length @ #, CountDistinct @ #} & @ colorswithdefaultplotstyle

{20, 15}

This works for all 113 indexed colors.

$Version

11.3 .0 for Microsoft Windows (64 - bit) (March 7, 2018)

$\endgroup$
3
  • $\begingroup$ Crazy! I always thought they were cyclic and it never occurred to me to check. $\endgroup$
    – Mr.Wizard
    Feb 5, 2020 at 20:59
  • $\begingroup$ I rather like this illustration: Grid[Partition[ColorData[97] /@ Range[500], 21], Spacings -> {0, -0.1}] $\endgroup$
    – Mr.Wizard
    Feb 5, 2020 at 21:26
  • $\begingroup$ @Mr.Wizard, great idea. I updated with a variation of your suggestion. $\endgroup$
    – kglr
    Feb 5, 2020 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.