7
$\begingroup$

In this toy example I make some plots, each with a legend, and combine them with Show. All the legends are assembled into a column which is helpful but it is too high for the size of plot. How can I make the row spacing in the column smaller?

plots = Table[
   Plot[x i, {x, 0, 1},
    PlotStyle -> {Hue[i/11]},
    PlotLegends -> 
     LineLegend[{"Serial " <> ToString[i]}, 
      LabelStyle -> {FontFamily -> "Times", 10}],
    Frame -> True, FrameLabel -> {"x", "y"},
    ImageSize -> 4 72,
    BaseStyle -> {FontFamily -> "Times", FontSize -> 10}],
   {i, 10}
   ];
Show[plots, PlotRange -> All]

Mathematica graphics

Thanks

$\endgroup$

3 Answers 3

8
$\begingroup$

Update 2: Post-processing plots without having to create a new legend:

Legended[Show[plots[[;; , 1]], PlotRange -> All], 
 Column[Join @@ plots[[;; , 2, All, 1]], Spacings -> -.8]]

Mathematica graphics

Legended[Show[plots[[;; , 1]], PlotRange -> All],
 Placed[Column[Join @@ plots[[;; , 2, All, 1]], Spacings -> -.8], {Before, Top}]]

Mathematica graphics

Original post:

Use the (afaik) undocumented option "Spacings" for LineLegend:

legend = LineLegend[Hue[#/11] & /@ Range[10], ("Serial " <> ToString[#]) & /@ Range[10],
   LabelStyle -> {FontFamily -> "Times", 10},
   "Spacings" -> {1, .2}]

or use LegendLayout with a custom layout function:

legend = LineLegend[Hue[#/11] & /@ Range[10], ("Serial " <> ToString[#]) & /@ Range[10],
  LabelStyle -> {FontFamily -> "Times", 10}, 
  LegendLayout -> (Grid[#, Spacings -> {1, .2}] &)]

to get

Mathematica graphics

You can then use legend with Legended

Legended[Plot[(# x) & /@ Range[10], {x, 0, 1}, Evaluated -> True, 
  PlotStyle -> (Hue[#/11] & /@ Range[10]), Frame -> True, 
  FrameLabel -> {"x", "y"}, ImageSize -> 4 72, 
  BaseStyle -> {FontFamily -> "Times", FontSize -> 10}], legend]

or with PlotLegends

Plot[(# x) & /@ Range[10], {x, 0, 1}, Evaluated -> True, 
 PlotStyle -> (Hue[#/11] & /@ Range[10]), Frame -> True, 
 FrameLabel -> {"x", "y"}, ImageSize -> 4 72, 
 BaseStyle -> {FontFamily -> "Times", FontSize -> 10}, 
 PlotLegends -> legend]

we get

Mathematica graphics

Update: If you do not want to redo the Plots you can use your plots with legend as follows:

Legended[Show[plots[[;;, 1]], PlotRange -> All], legend]

Mathematica graphics

$\endgroup$
5
  • $\begingroup$ @Hugh, thought the question was about legend row spacings, no?:) $\endgroup$
    – kglr
    Commented May 29, 2016 at 21:02
  • $\begingroup$ Yes it was and you answered it directly. What I have done is to take his method of reconstructing and then use your spacings method. Perhaps I will give you the credit after all. $\endgroup$
    – Hugh
    Commented May 29, 2016 at 21:05
  • $\begingroup$ @Hugh, i did not mean to suggest that you re-consider your accept decision. You should feel free to accept any answer that you find most useful. $\endgroup$
    – kglr
    Commented May 29, 2016 at 21:18
  • $\begingroup$ You were correct to point out that spacings is the issue. You answered that and should get the credit. However, xslittlegrass idea of reconstructing was also helpful but did not deal with spacing. $\endgroup$
    – Hugh
    Commented May 29, 2016 at 21:22
  • $\begingroup$ The answer is getting better and better. Unfortunately I cannot keep giving you more and more upvotes. Thanks for your continued help. $\endgroup$
    – Hugh
    Commented Jun 5, 2016 at 11:14
4
$\begingroup$

Sometimes, you may not want to reconstruct the legend from scratch then you can extract the legends from the plots, and make adjustments on them, for example

p=Show[plots, PlotRange -> All];

opt = First@Cases[plots[[1]], LineLegend[x_List, y_List, opt__] :> {opt}, ∞];

lgd = LineLegend[
  Sequence @@ 
   Transpose[
    First@Cases[#, 
        LineLegend[x_List, y_List, opt__] :> {x, y}, ∞] & /@
      plots], Sequence @@ FilterRules[opt, Except[LegendLayout]], 
  LegendLayout -> {"Column", 2}]

Legended[First@Cases[p, Graphics[___], ∞], lgd]

enter image description here

Or

lgd = LineLegend[
  Sequence @@ 
   Transpose[
    First@Cases[#, 
        LineLegend[x_List, y_List, opt__] :> {x, y}, ∞] & /@
      plots], Sequence @@ FilterRules[opt, Except[LegendLayout]], 
  LegendLayout -> {"Row", 2}]

Legended[First@Cases[p, Graphics[___], ∞], Placed[lgd, Bottom]]

enter image description here

$\endgroup$
4
  • $\begingroup$ Thanks, I like not having to reconstruct. I think you may have defined p = Show[plots, PlotRange -> All]. Legended seems to be the way forward. $\endgroup$
    – Hugh
    Commented May 28, 2016 at 9:36
  • $\begingroup$ Right, I have corrected that. $\endgroup$ Commented May 28, 2016 at 14:48
  • $\begingroup$ Sorry I can't select your answer. Your method of reconstructing is good but the question is about spacing. So really kglr should get the credit. Pity I can't give it to both of you. I have used your method of reconstructing. $\endgroup$
    – Hugh
    Commented May 29, 2016 at 21:07
  • $\begingroup$ No worry! I just want to share this, glad it helped :) $\endgroup$ Commented May 29, 2016 at 21:11
3
$\begingroup$

The option LegendMargins can be used to significantly reduce the spacing.

This option can be added directly to LineLegend

plots = Table[
   Plot[x i, {x, 0, 1}, PlotStyle -> {Hue[i/11]}, 
    PlotLegends -> 
     LineLegend[{"Serial " <> ToString[i]}, LabelStyle -> {FontFamily -> "Times", 10}, 
      LegendMargins -> {0, 0}], 
    Frame -> True, FrameLabel -> {"x", "y"}, ImageSize -> 4 72, 
    BaseStyle -> {FontFamily -> "Times", FontSize -> 10}], {i, 10}];
Show[plots, PlotRange -> All]

Plot1

or after the plots were produced.

plots = Table[
   Plot[x i, {x, 0, 1}, PlotStyle -> {Hue[i/11]}, 
    PlotLegends -> 
     LineLegend[{"Serial " <> ToString[i]}, LabelStyle -> {FontFamily -> "Times", 10}], 
    Frame -> True, FrameLabel -> {"x", "y"}, ImageSize -> 4 72, 
    BaseStyle -> {FontFamily -> "Times", FontSize -> 10}], {i, 10}];
Show[plots /. LineLegend[ll__] :> LineLegend[ll, LegendMargins -> {0, 0}], PlotRange -> All]

Plot2

To have the legends starting at the top, one additional replacement is needed.

Show[plots /. 
   LineLegend[ll__] :> LineLegend[ll, LegendMargins -> {0, 0}] /. After -> {After, Top}, 
 PlotRange -> All]

Plot3

Negative margin values reduce the spacing even further.

Show[plots /. LineLegend[ll__] :> LineLegend[ll, LegendMargins -> {{5, 0}, {-5, -5}}] /. 
  After -> {After, Top}, PlotRange -> All]

Plot4

$\endgroup$
1
  • $\begingroup$ Another very helpful approach. It seems that there is more available than I thought or could find. Thanks $\endgroup$
    – Hugh
    Commented Jun 5, 2016 at 11:15

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.