Mathematica: Can I match the BarChart Legend to the stacked bars?
Asked Answered
B

3

6

I would like to have the vertical arrangement of colors in stacked bars match the arrangement of colors in the chart legend. But no matter what I try, they don't match. Here's the situation

BarChart[{{5, 37, 56}, {22, 49, 28}, {31, 60, 10}},
   ChartLayout -> "Percentile",
   ChartLegends -> Placed[{"1-Volume", "2-Area", "3-Length"}, Right],
   ChartLabels -> {{"Before", "During", "After"}, None}]

Chart1

In the real-world example the legend has quite a few more entries (6), so it would be nice if the order of the legend colors matched the order in the bars. I realize that I could set the ChartLegends to display at Bottom, but doesn't look good given the many legend entries.

Also, reversing the Legends list does not work as desired. The text of the legends was re-ordered, but the colors were not reordered (see below), so the legend captions no longer match the data in the chart.

Changing the order of the data (or the data and the legend items) does not work either.

Any suggestions?

enter image description here

Bummalo answered 19/9, 2011 at 21:4 Comment(0)
P
10
BarChart[{{5, 37, 56}, {22, 49, 28}, {31, 60, 10}}, 
  ChartLayout -> "Percentile", 
  ChartLegends -> {"1-Volume", "2-Area", "3-Length"}, 
  ChartLabels -> {{"Before", "During", "After"}, None}] /. 
 Column[List[a : Grid[List[___]] ..]] :> Column[Reverse@List@a]

enter image description here

Edit

Remember to use FullForm when you want to mess up with Graphics/Chart/Plot internals

Perilymph answered 19/9, 2011 at 21:36 Comment(3)
My goodness. I never would have thought to do that. So you changed the order of the legends after issuing the BarChart command?Bummalo
@David Try the following Barchart[ ....] // FullForm and look at the Column command almost at the end :)Perilymph
That's very enlightening. Thanks.Bummalo
S
6

Building on the nice answer given by Belisarius, an alternative method using Part

bc[[2,1,1,1]]= Reverse@bc[[2,1,1,1]];bc

This may be inferred from FullForm and

Position[bc, #, Infinity]& /@ {Framed[___],
Column[___],List[___,"1-Volume",___]}

or from any one of these, perhaps, and trial-and-error.

Although not part of the question, Simon's trick (see here) may be used to further manipulate the legend.

bc/.Labeled[g_,Framed[leg_],pos_]:>
Labeled[g,Framed[leg,FrameStyle->Orange,RoundingRadius->10,
Background->LightYellow],pos]

for example, gives the following:

enter image description here

Part may also be used to remove the frame around the legend (see this question) but Simon's method is much more versatile.

bc[[2]]=bc[[2,1]];bc
Siskin answered 20/9, 2011 at 10:3 Comment(1)
Nice work! I hadn't realized how deep into the innards of a chart one can go. My legend looks very large. I think I was in presentation mode; it affected the legend fontsize by not the other fonts. BTW, it is a pleasure to push you over 2k.Bummalo
C
2

You can use LegendContainer for this.

SetOptions[Legending`GridLegend, 
  Legending`LegendContainer -> (Framed@MapAt[Reverse, #, {1, 1}] &)];

BarChart[{{5, 37, 56}, {22, 49, 28}, {31, 60, 10}}, 
 ChartLayout -> "Percentile", 
 ChartLegends -> {"1-Volume", "2-Area", "3-Length"}, 
 ChartLabels -> {{"Before", "During", "After"}, None}]

same as belisarius' graph

Client answered 19/10, 2011 at 0:35 Comment(1)
@David thank you. See my other use of it here.Client

© 2022 - 2024 — McMap. All rights reserved.