9

BarLegend has an annoyingly large space at the bottom. I can see that this was added to make it line up with the frame of the plot when there is a bottom frame label (see e.g. here), but this does not work out well for all plot sizes, and it causes problems in specific situations.

How can I control this space?

Select the legend to see the spacing better:

enter image description here

This space is also much too large for a legend label placed below the legend.

Row[
 {Framed@BarLegend["Rainbow", 
    Method -> {ImagePadding -> None, ImageMargins -> None, 
      PlotRangePadding -> None}, LegendMargins -> 0, 
    LegendLabel -> "foo"],
  Framed@BarLegend["Rainbow", 
    Method -> {ImagePadding -> None, ImageMargins -> None, 
      PlotRangePadding -> None}, LegendMargins -> 0, 
    LegendLabel -> Placed["foo", Below]]}
 ]

enter image description here

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263

2 Answers2

7

You can pass negative values to LegendMargins like so:

BarLegend["Rainbow", LegendMargins -> {{0, 0}, {-15, 0}}]

enter image description here

Happily, this appears to work quite stably, even though it feels wrong:

Row[{Framed@
   BarLegend["Rainbow", 
    Method -> {ImagePadding -> None, ImageMargins -> None, 
      PlotRangePadding -> None}, LegendMargins -> {{0, 0}, {-15, 0}}, 
    LegendLabel -> "foo"], 
  Framed@BarLegend["Rainbow", 
    Method -> {ImagePadding -> None, ImageMargins -> None, 
      PlotRangePadding -> None}, LegendMargins -> {{0, 0}, {-15, 0}}, 
    LegendLabel -> Placed["foo", Below]]}]

enter image description here

I am a little disappointed that the "zero-point" still has such a large margin on it - having to pass negative values feels like a hack. I almost wish it didn't work so the margin could be called a bug...

Carl Lange
  • 13,065
  • 1
  • 36
  • 70
  • It's really ugly, but I was not able to find any other solution, and I'm happy that it moves things forward. – Szabolcs Oct 30 '19 at 12:01
  • 1
    (+1) If we replace LegendLabel -> "foo" with LegendLabel["foo", Above], then we can use slightly simpler form Row[Framed@ BarLegend["Rainbow", LegendMargins -> {{0, 0}, {-15, 0}}, LegendLabel -> Placed["foo",#]]&/@{Above, Below}] without the need for Method suboptions. – kglr Oct 30 '19 at 15:38
3

You can also use a custom LegendFunction (to inject the option ImagePadding -> {{Automatic, Automatic}, {0, Automatic}} to the graphics object produced by BarLegend)

ClearAll[lgF]
lgF = Show[Cases[#, _Graphics, All],
  ImagePadding -> {{Automatic, Automatic}, {0, Automatic}}]&;

Row[Framed @ BarLegend["Rainbow", 
   LegendLabel -> Placed["foo", #], 
   LegendFunction -> lgF] & /@ {Above, Below}]

enter image description here

Somehow, using the same option as a Method sub-option does not work. (Apparently, it is overridden during processing.)

kglr
  • 394,356
  • 18
  • 477
  • 896