27
$\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$
  • $\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 '12 at 5:40
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$
  • $\begingroup$ great thank you! $\endgroup$ – Julia Mar 26 '12 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$
  • $\begingroup$ Thanks for this solution. How do I add instead of a dashed line, traingles or circle markers? $\endgroup$ – Santi Feb 26 '14 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$
  • 4
    $\begingroup$ You could also use Legended instead of Grid: Legended[Show[{plot, line, line2}], LineLegend[{style1, style2, style3}, {"plot", "line", "line2"}]] $\endgroup$ – Chip Hurst Nov 30 '15 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$
  • $\begingroup$ You don't need InputForm for this. The Graphics expression is directly manipulable. $\endgroup$ – Mr.Wizard Mar 27 '12 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$ – István Zachar Mar 28 '12 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$
  • $\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 '12 at 11:34

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.