15
$\begingroup$

In a stacked BarChart or Histogram the bars are stacked from bottom to top, while the legend entries are listed from top to bottom. Is there a way to make the legend entries go the other way round to improve the visual correspondence between the chart and the legend?

E.g.

{bottom,middle,top}=RandomReal[NormalDistribution[0,1],{3,200}];
Histogram[{bottom,middle,top},10,ChartLayout->"Stacked",ChartLegends->{"Bottom","Middle","Top"}]

histogram

$\endgroup$
3

5 Answers 5

17
$\begingroup$
Histogram[{bottom, middle, top}, 10, 
          ChartLayout -> "Stacked", 
          ChartLegends -> {"Bottom", "Middle", "Top"}] /. 
Column[l_List] :> Column[Reverse@l]

enter image description here

$\endgroup$
4
  • $\begingroup$ Slick answer! +1 $\endgroup$
    – Eli Lansey
    Commented Apr 20, 2012 at 22:04
  • $\begingroup$ I just checked out that linked question. That's also a really slick answer! $\endgroup$
    – Eli Lansey
    Commented Apr 20, 2012 at 22:10
  • $\begingroup$ This is great, thanks. It seems so obvious now! $\endgroup$ Commented Apr 21, 2012 at 11:08
  • 1
    $\begingroup$ @SimonWoods It is not obvious at all if you don't run Histogram[...]//FullForm first :) $\endgroup$ Commented Apr 21, 2012 at 15:19
11
$\begingroup$

Using belisarius' method, if you want to reverse the order for all vertical legends you could use Legending`LegendContainer like this:

{bottom, middle, top} = RandomReal[NormalDistribution[0, 1], {3, 200}];

SetOptions[Legending`GridLegend, 
  Legending`LegendContainer -> (Framed[# /. Column[l_List] :> Column[Reverse@l]] &)
];

Histogram[{bottom, middle, top}, 10,
  ChartLayout -> "Stacked",
  ChartLegends -> {"Bottom", "Middle", "Top"}
]

Mathematica graphics

$\endgroup$
2
  • $\begingroup$ Legending sounds like a pejorative adjective for the works of people like JK Rowling $\endgroup$ Commented Apr 21, 2012 at 2:14
  • 1
    $\begingroup$ @belisarius you always find something to make me laugh. :D $\endgroup$
    – Mr.Wizard
    Commented Apr 21, 2012 at 2:15
7
$\begingroup$

This solution will no longer work in Mathematica 9 because they now use SwatchLegend in FullForm. Instead, apply this:

Histogram[{bottom, middle, top}, 10, ChartLayout -> "Stacked", 
ChartLegends -> {"Bottom", "Middle", "Top"}] /. 
SwatchLegend[l1_List, l2_List, r1_Rule, r2_Rule] :> 
SwatchLegend[Reverse[l1, 1], Reverse[l2, 1], r1, r2]

The integer parameter in Reverse[l1,1] and Reverse[l2,1] might have to be tweaked; in some cases I had to reverse within the second level instead of the first. //FullForm should give you enough hints.

$\endgroup$
3
  • $\begingroup$ Where can I learn more about this type of syntax, eg. the l1_List and ri_Rule stuff? I'm not exactly sure how this is working, nor do I know how to use FullForm to help figure this out. I'm trying to flip a legend on a ListLogLogPlot using SwatchLegend. $\endgroup$
    – skratch
    Commented May 24, 2013 at 17:08
  • $\begingroup$ Ah, I got it! Seems a regular Plot only has one Rule following the two List elements in the FullForm of SwatchLegend. Removing r2_Rule and r2 in the delayed replacement does the trick. $\endgroup$
    – skratch
    Commented May 24, 2013 at 17:47
  • $\begingroup$ Yea that is exactly right. $\endgroup$ Commented Jul 7, 2013 at 21:27
6
$\begingroup$

belisarius beat me to the Column replacement rule method. An alternative method would be to use ShowLegend to construct the legend manually, taking the code for the layout from the FullForm of your original graphic. The ridiculously complex lokking color specifications happen to be the Mathematica defaults for bar charts.

ShowLegend[ Histogram[{bottom, middle, top}, 10,  ChartLayout -> "Stacked"], 
 {{{Graphics[{GrayLevel[0.9], 
      Directive[GrayLevel[0.85], EdgeForm[Opacity[0.7]], Opacity[0.5],
        RGBColor[0.6, 0.5470136627990908, 0.24]], 
      Rectangle[{0, 0}, {1, 1}]}, {ImageSize -> 10}], 
    "Top"}, {Graphics[{GrayLevel[0.9], 
      Directive[GrayLevel[0.85], EdgeForm[Opacity[0.7]], Opacity[0.5],
        RGBColor[0.6, 0.24, 0.4428931686004542]], 
      Rectangle[{0, 0}, {1, 1}]}, {ImageSize -> 10}], 
    "Middle"}, {Graphics[{GrayLevel[0.9], 
      Directive[GrayLevel[0.85], EdgeForm[Opacity[0.7]], Opacity[0.5],
        RGBColor[0.2472, 0.24, 0.6]], 
      Rectangle[{0, 0}, {1, 1}]}, {ImageSize -> 10}], "Bottom"}}, 
  LegendPosition -> {0.25, 0.2}, LegendBackground -> White, 
  LegendBorder -> None, LegendShadow -> None, 
  LegendSize -> {0.6, 0.35}, LegendBorder -> None, 
  LegendTextSpace -> 3}]

enter image description here

$\endgroup$
0
5
$\begingroup$

As pointed out, Belisarius' method no longer works on v9. But, there are built in tools that do not require additional manipulation to work. LineLegend, PointLegend, and SwatchLegend all accept the form

LegendFunction[{lbl1, lbl2, ...}, options]

where {lbl1, lbl2, ...} are the legend labels, and the legend function will pick up the styles of the chart/plot automatically. This also works with Automatic and "Expressions", where appropriate. The key here is that the three legends can be then interchanged at will, and additional options can be supplied to change how they are displayed. In this case, the option you are looking for is LegendLayout, specifically, "ReversedColumn":

Histogram[{bottom, middle, top}, 10, ChartLayout -> "Stacked", 
 ChartLegends -> 
  SwatchLegend[{"Bottom", "Middle", "Top"}, 
   LegendLayout -> "ReversedColumn"
  ]
]

enter image description here

Or, if you are curious

enter image description here

$\endgroup$

Your Answer

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

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