I am creating an application for various kinds of plot/chart drawing in Mathematica. Ultimately it will have a GUI, but the first step is to get the code right, and simple enough for a GUI to manage. I am having difficulty setting legends to have no frame around them.
Here is a minimal example (with some options on BarChart
already customised using SetOptions
.
mydata = {4.5644, 5.546, 6.8674, 2.7688, 1.742, 5.3952, 4.3392, 4.5016, \
3.7748, 1.838, 2.24, 0.693, 2.818, 4.9, 3.939, 3.459, 3.755, 4.475, \
3.857, 3.215, 2.206, 2.206, 2.117, 3.403, 3.277, 3.761, 4.276, 2.559, \
3.486, 4.778, 2.281, 2.865, 3.629, 4.916, 4.572, 5.244, 5.395, 2.865, \
-0.524, 5.01, 4.401, 4.513, 4.54}
BarChart[mydata,
ChartStyle -> {Join[
Table[RGBColor[0.5, 0.5, 0.95], {Length[mydata] - 3}], {Magenta,
Magenta, Magenta}]}, PlotRange -> {-2, 8},
ChartLegends -> {Join[
Table[None, {Length[mydata] - 3}], {Placed[
Style["Forecasts", FontFamily -> "Arial", FontSize -> 18],
Bottom]}]}, BarSpacing -> 0.4,
LegendAppearance -> Directive[Background -> Red,
Frame -> None, ImageSize -> 15]]
And here is what I get:
Try as I might, I can't get rid of that border round the legend. You can see that LegendAppearance
does nothing - I've tried a few other approaches to it, too.
I'm reticent to code up little rectangles by hand, because that will be very difficult to get right in the eventual GUI. ChartLabels
won't work either, because that is already being used for date labels in the real version of the graph.
Does anyone have any suggestions?
I can't find any options to turn the frame off. The documentation for LegendAppearance is fairly minimal and the styling of legends in general does not get much discussion (see [2] and links within).
The easiest solution I can think of is to manually modify the graphics. Charts with legends produce Labeled graphics objects. For a single legend, the Labeled
object that is produced looks like Labeled[Graphics[...], Framed[...], pos]
, so all you need to do is remove the Framed
part. This could be done just be removing all Framed
heads using a ReplaceAll
(e.g. BarChart[...] /. Framed -> Identity
), but maybe something more targeted would be safer.
mydata = {4.5644, 5.546, 6.8674, 2.7688, 1.742, 5.3952, 4.3392,
4.5016, 3.7748, 1.838, 2.24, 0.693, 2.818, 4.9, 3.939, 3.459,
3.755, 4.475, 3.857, 3.215, 2.206, 2.206, 2.117, 3.403, 3.277,
3.761, 4.276, 2.559, 3.486, 4.778, 2.281, 2.865, 3.629, 4.916,
4.572, 5.244, 5.395, 2.865, -0.524, 5.01, 4.401, 4.513, 4.54};
bc = BarChart[{Legended[Style[mydata[[;; -4]], Red], "Data"],
Legended[Style[mydata[[-3 ;;]], Blue], "Forecasts"]},
PlotRange -> {-2, 8}, BarSpacing -> 0.4, LegendAppearance -> "Row"]
bc /. Labeled[g_, Framed[leg_], pos_] :> Labeled[g, leg, pos]
The above could also be produced using Replace[bc, Framed[leg_] :> leg, {1}]
or MapAt[Apply[Identity, #] &, bc, 2]
or similar constructions. It wouldn't take much to modify the code if you have more labels or different types of graphics objects.
You can temporarily, globally kill the frame by setting:
SetOptions[Legending`GridLegend, Legending`LegendContainer -> Identity]
To restore the default behavior, set:
SetOptions[Legending`GridLegend, Legending`LegendContainer -> Automatic]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With