28
$\begingroup$

I have already obtained the plot that I want but am having trouble legending the graph correctly.

plot = ListLogLogPlot[Sort[depth4], PlotRange -> {{1, 50000}, {1, 50000}}, Joined -> True, 
PlotStyle -> {Purple}, BaseStyle -> {FontSize -> 14}];

line = LogLogPlot[11024 x^(-0.94232), {x, 1, 100000}, 
   PlotStyle -> {Orange, Dashed, Thick}];
line2 = LogLogPlot[31862 x^(-1.07076), {x, 1, 100000}, 
   PlotStyle -> {Green, Dotted, Thick}];

Show[plot, line, line2]

If I insert a legend command into the first plot, it doesn't work. I need to be able to legend my 3 curves in the graph. Thanks for your help!

$\endgroup$
1
  • $\begingroup$ Clearly the main objective here is to have a single legend for several different plots. A related problem, addressed below by F'x, is to make a legend for a single plot with several lines or data sets. That issue is also addressed in this question: mathematica.stackexchange.com/questions/4025/… $\endgroup$
    – Jens
    Apr 9, 2012 at 5:40

7 Answers 7

20
$\begingroup$

When Show is used the legends use ShowLegend. Here is a demo:

depth4 = Range[20]^3;
plot = ListLogLogPlot[Sort[depth4], PlotRange -> {{1, 50000},
     {1, 50000}}, Joined -> True, PlotStyle -> {Purple},
   BaseStyle -> {FontSize -> 14}];
line = LogLogPlot[11024 x^(-0.94232), {x, 1, 100000},
   PlotStyle -> {Orange, Dashed, Thick}];
line2 = LogLogPlot[31862 x^(-1.07076), {x, 1, 100000},
   PlotStyle -> {Green, Dotted, Thick}];

Needs["PlotLegends`"]
ShowLegend[Show[plot, line, line2, ImageSize -> 500],
 {{{Graphics[{Purple, Line[{{0, 0}, {2, 0}}]}], "   depth4"},
   {Graphics[{Orange, Dashed, Line[{{0, 0}, {2, 0}}]}], "   line"},
   {Graphics[{Green, Dashed, Line[{{0, 0}, {2, 0}}]}], "   line2"}},
  LegendPosition -> {0.7, 0.2}, LegendSize -> {0.45, 0.4},
  LegendShadow -> False}]

enter image description here

$\endgroup$
1
  • $\begingroup$ great thank you! $\endgroup$
    – Julia
    Mar 26, 2012 at 11:34
29
$\begingroup$

While in many ways Mathematica's graphics is miles ahead of its competition, the supplied legend package looks like a hack that does not belong. In its own documentation, under Inset, you will find examples of better looking legends. Building on those examples, I have a simple legend function.

ClearAll[simpleLegend]
simpleLegend[legendItems__,pos_]:=Module[{legendLine,offset,legend},
  offset=Module[{s,o,insetpts=10},
    s=pos/.{Left->0,Right->1,Bottom->0,Top->1};
    o=insetpts pos/.{Left->1,Right->-1,Bottom->1,Top->-1};
    Offset[o,Scaled[s]]
  ];
  legendLine[{lbl_,lineStyle_}]:={
    Graphics[{lineStyle,Line[{{0,0.5},{1,0.5}}]},ImageSize->{20,10},AspectRatio->0.5],
    Style[lbl,FontFamily->"Tahoma",FontSize->11,TextAlignment->Left,LineBreakWithin->False]
  };
  legend=GraphicsGrid[legendLine/@legendItems,Alignment->Left];
  Graphics@Inset[legend,offset,pos]
];

which can be used like this

labels={"data","eq1","eq2"};
styles={Directive[Purple],Directive[Orange,Dashed,Thick],Directive[Green,Dotted,Thick]};

depth4=Table[{x,(11024 x^(-0.94232))*RandomReal[{0.4,1.6}]}/.x->10^n,{n,0,5,0.1}];

plot=ListLogLogPlot[Sort[depth4],
  PlotRange->{{1,50000},{1,50000}},Joined->True,PlotStyle->styles[[1]],
    BaseStyle->{FontSize->14}
];

line=LogLogPlot[11024 x^(-0.94232),{x,1,100000},PlotStyle->styles[[2]]];
line2=LogLogPlot[31862 x^(-1.07076),{x,1,100000},PlotStyle->styles[[3]]];

Show[plot,line,line2,simpleLegend[Thread@{labels,styles},{Right,Top}]]

enter image description here

$\endgroup$
1
  • $\begingroup$ Thanks for this solution. How do I add instead of a dashed line, traingles or circle markers? $\endgroup$
    – Santiago
    Feb 26, 2014 at 11:46
14
$\begingroup$

You can also use Epilog->Inset[...] as follows:

For

  depth4 = Range[20]^3; 
  plot =  ListLogLogPlot[Sort[depth4], PlotRange -> {{1, 50000}, {1, 50000}}, 
  Joined -> True, PlotStyle -> {Purple}, BaseStyle -> {FontSize -> 14}]; 
  line = LogLogPlot[11024 x^(-0.94232), {x, 1, 100000}, 
  PlotStyle -> {Orange, Dashed, Thick}]; 
  line2 = LogLogPlot[31862 x^(-1.07076), {x, 1, 100000}, 
  PlotStyle -> {Green, Dotted, Thick}];

as in Chris's answer,

 Show[plot, line, line2, ImageSize -> 500, 
 Epilog -> 
 Inset[Panel[
 Grid[{{Graphics[{Purple, 
 Line[{{0, 0}, {2, 0}}]}, AspectRatio -> .1, ImageSize -> 30], 
   Style["depth4", FontFamily -> "SketchFlowPrint", Bold, FontColor -> Purple]}, 
  {Graphics[{Orange, Dashed, 
     Line[{{0, 0}, {2, 0}}]}, AspectRatio -> .1, ImageSize -> 30],
    Style["line", FontFamily -> "SketchFlowPrint", Bold, FontColor -> Orange]}, 
  {Graphics[{Green, Dotted, 
     Line[{{0, 0}, {2, 0}}]}, AspectRatio -> .1, ImageSize -> 30],
    Style["line2", FontFamily -> "SketchFlowPrint", Bold, FontColor -> Green]}}, 
 Alignment -> {{Left, Left}, {Left, Left}}], ImageSize -> Full], 
 Offset[{-2, -2}, Scaled[{1, 1}]], {Right, Top}]]

gives

enter image description here

$\endgroup$
7
$\begingroup$

In Mathematica 10.3 you can use LineLegend. I myself have never liked to have a legend within the plot, so I insert it in a grid.

depth4 = Range[20]^3;
style1 = Directive[Purple];
plot = ListLogLogPlot[Sort[depth4], 
   PlotRange -> {{1, 50000}, {1, 50000}}, Joined -> True, 
   PlotStyle -> style1, BaseStyle -> {FontSize -> 14}];
style2 = Directive[Orange, Dashed, Thick];
line = LogLogPlot[11024 x^(-0.94232), {x, 1, 100000}, 
   PlotStyle -> style2];
style3 = Directive[Green, Dotted, Thick];
line2 = LogLogPlot[31862 x^(-1.07076), {x, 1, 100000}, 
   PlotStyle -> style3];
temp = Grid[{{
    Show[{plot, line, line2}, ImageSize -> 300]
    , LineLegend[{style1, style2, style3}, {"plot", "line", "line2"}]
    }}]
Export[NotebookDirectory[] <> "plot_linelegend.png", temp]

If you save the notebook somewhere, you will obtain directly a png image of the plot with the legend as this one

Grid with plot and line legend

$\endgroup$
1
  • 4
    $\begingroup$ You could also use Legended instead of Grid: Legended[Show[{plot, line, line2}], LineLegend[{style1, style2, style3}, {"plot", "line", "line2"}]] $\endgroup$
    – Greg Hurst
    Nov 30, 2015 at 16:48
7
+200
$\begingroup$

I'm using version 10.2, and it seems that the legends from the initial plots work just fine with Show

depth4 = Range[20]^3;
plot = ListLogLogPlot[Sort[depth4], 
   PlotRange -> {{1, 50000}, {1, 50000}}, Joined -> True, 
   PlotStyle -> {Purple}, BaseStyle -> {FontSize -> 14}, 
   PlotLegends -> {"plot"}];

line = LogLogPlot[11024 x^(-0.94232), {x, 1, 100000}, 
   PlotStyle -> {Orange, Dashed, Thick}, PlotLegends -> {"line"}];
line2 = LogLogPlot[31862 x^(-1.07076), {x, 1, 100000}, 
   PlotStyle -> {Green, Dotted, Thick}, PlotLegends -> {"line2"}];

Show[plot, line, line2]

enter image description here

You'll notice that the purple line is smaller, because for some reason Mathematica makes the legend line longer if there is dashing. If we make the purple line dashed (but not really dashed), then they are consistent.

plot = ListLogLogPlot[Sort[depth4], 
   PlotRange -> {{1, 2 50000}, {1, 50000}}, Joined -> True, 
   PlotStyle -> {Purple,Dashing[{1, 0}]}, 
   BaseStyle -> {FontSize -> 14}, PlotLegends -> {"plot"}];
Show[plot, line, line2]

enter image description here

$\endgroup$
6
$\begingroup$

You can extract Line directives (color, thickness, dashing, etc. specifications) from the plot itself. This means that you don't have to call for a second time for the style specifications explicitly. For complex graphics (with e.g. plot markers) it might not be this simple though.

depth4 = Range[20]^3;
plot = ListLogLogPlot[Sort[depth4], 
   PlotRange -> {{1, 50000}, {1, 50000}}, Joined -> True, 
   PlotStyle -> {Purple}, BaseStyle -> {FontSize -> 14}];
line = LogLogPlot[11024 x^(-0.94232), {x, 1, 100000}, 
   PlotStyle -> {Orange, Dashed, Thick}];
line2 = LogLogPlot[31862 x^(-1.07076), {x, 1, 100000}, 
   PlotStyle -> {Green, Dotted, Thick}];

data = Show[plot, line, line2];
styles = Cases[data, {dir__, l_Line} :> {dir}, \[Infinity]]
{{Hue[0.67, 0.6, 0.6], RGBColor[0.5, 0, 0.5]}, {Hue[0.67, 0.6, 0.6], 
  RGBColor[1, 0.5, 0], Dashing[{Small, Small}], 
  Thickness[Large]}, {Hue[0.67, 0.6, 0.6], RGBColor[0, 1, 0], 
  Dashing[{0, Small}], Thickness[Large]}}
Row@{
  Show[plot, line, line2, ImageSize -> 300],
  Grid[Table[{Graphics[Append[styles[[i]], Line[{{0, 0}, {1, 0}}]], 
      ImageSize -> 50, AspectRatio -> 1/5], "plot" <> ToString@i}, {i,
      3}], Spacings -> {1, 2}]
  }

Mathematica graphics

$\endgroup$
2
  • $\begingroup$ You don't need InputForm for this. The Graphics expression is directly manipulable. $\endgroup$
    – Mr.Wizard
    Mar 27, 2012 at 5:36
  • 1
    $\begingroup$ @Mr.Wizard you're right, thanks for pointing it out. I guess this was just some bad habit surviving from pre-6 times. $\endgroup$ Mar 28, 2012 at 18:19
5
$\begingroup$

I don't know of a direct way to do that once the individual graphs have been plotted and legended. You can, however, use ListLogLogPlot on a table containing values from your functions, so as to have a single call to a Plot function, which can thus take a PlotLegend option:

Needs["PlotLegends`"];
ListLogLogPlot[{
  Sort[depth4],
  Table[{x, 11024 x^(-0.94232)} /. x -> 10^n, {n, 0, 5, 0.1}],
  Table[{x, 31862 x^(-1.07076)} /. x -> 10^n, {n, 0, 5, 0.1}]
  },
 PlotRange -> {{1, 50000}, {1, 50000}},
 Joined -> True,
 PlotStyle -> {Purple, Directive[Orange, Dashed, Thick], 
   Directive[Green, Dotted, Thick]},
 BaseStyle -> {FontSize -> 14},
 PlotLegend -> {"data", "eq1", "eq2"}]

resulting plot


PS: you were missing the definitio for depth4, so I took:

depth4 = Table[{x, (11024 x^(-0.94232))*RandomReal[{0.4, 1.6}]} /. x -> 10^n, {n, 0, 5, 0.1}];
$\endgroup$
1
  • $\begingroup$ Thanks a lot, however Chris Degnen's method is easier for me as i have to do this with many graphs. :) $\endgroup$
    – Julia
    Mar 26, 2012 at 11:34

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.