5
$\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$
6
$\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$
  • $\begingroup$ @Hugh, thought the question was about legend row spacings, no?:) $\endgroup$ – kglr May 29 '16 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 May 29 '16 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 May 29 '16 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 May 29 '16 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 Jun 5 '16 at 11:14
3
$\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$
  • $\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 May 28 '16 at 9:36
  • $\begingroup$ Right, I have corrected that. $\endgroup$ – xslittlegrass May 28 '16 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 May 29 '16 at 21:07
  • $\begingroup$ No worry! I just want to share this, glad it helped :) $\endgroup$ – xslittlegrass May 29 '16 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$
  • $\begingroup$ Another very helpful approach. It seems that there is more available than I thought or could find. Thanks $\endgroup$ – Hugh Jun 5 '16 at 11:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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