Google Groups

Re: Plot Legends For Side By Side Graphs


JUN Dec 8, 2011 2:40 AM
Posted in group: comp.soft-sys.math.mathematica
On Dec 3, 11:57 pm, Armand Tamzarian <mike.honeychu...@gmail.com>
wrote:
> On Dec 3, 8:17 pm, Brentt <brenttnew...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > Hello, I want to produce a plot legend for two Plots, with the same scale> ,
> > placed side by side using GraphicsGrid, to export and put in a document.
> > Both graphs the same legend, so I only want one legend for both graphs.
> > I've been using the "PlotLegends" package but it has some constraints I
> > can't figure out how to work around.
>
> > I want the legend keys to take on the color of the curves automatically.
> > Using the PlotLegend option does this automatically, but it needs to be an option in both plots, so I either duplicate the same legend for both plots,
> > or the scaling of the plot that I generate the legend for is botched if I
> > only generate the legend for one plot.
>
> > I've tried using the Legend function to generate a legend in order  to
> > expor it to a seperate image file to be placed in the document
> > independently.  There doesn't seem to be a way to have the keys take on the
> > curve colors automatically, as the PlotLegends option does.
>
> > Is there a way to produce one legend for two plots without messing up the
> > scaling of the plot, or to use Legend to generate keys that automatical
ly
> > take on the colors of the curves they correspond to?
>
> I'd steer clear of the legends package. And to be honest I don't
> remember seeing any stuff coming out of Wolfram that uses it.
> Having said that, here is a basic solution which may get you started:
>
> stuffToPlot = {Sin[x], Tan[x]};
> namesofStuffPlotted = {"Sin", "Tan"};
>
> legend = MapIndexed[
>    Row[{Spacer[10],
>       Graphics[{AbsoluteThickness[2], ColorData[1, First[#2]],
>         Line[{{0, 0}, {1, 0}}]}, AspectRatio -> 0.1, ImageSize -> 30],
>        Spacer[5], #1}] &, namesofStuffPlotted];
>
> Labeled[
>  GraphicsGrid[{
>    {Plot[stuffToPlot, {x, 0, 6}], Plot[stuffToPlot, {x, 0, 6}]}
>    }],
>  Row@legend, {{Bottom, Center}}]
>
> For a vertical legend just replace Row with Column. If you are using
> your own set of colours instead of the indexed ones then you would
> need to use MapThread instead of MapIndexed. If you want swatches
> instead of lines use Rectangle ...and so on.
>
> Mike

Another suggestion would be to use the following two functions
(legendMaker and markerSymbols):

legendMaker[lineDirectives_, markerSymbols_, textLabels_,
  opts : OptionsPattern[]] := Module[{f, g},
  f = Grid[MapThread[{
       Graphics[{#1,
         Line[{{-.1, 0}, {.1, 0}}],
         Inset[#2, {0, 0},
          Background -> None
          ]},
        AspectRatio -> .2, ImageSize -> 35],
       TraditionalForm[#3]} &, {
      lineDirectives, markerSymbols, textLabels
      }], Alignment -> Left];
  g = Framed[f,
    RoundingRadius -> (RoundingRadius /. {opts} /. {RoundingRadius ->
         10}), BaseStyle -> {FontFamily -> "Times New Roman",
      Background -> (Background /. {opts} /. {Background -> None})},
    FrameStyle -> (FrameStyle /. {opts} /. {FrameStyle -> None}),
    ImageMargins -> (ImageMargins /. {opts} /. {ImageMargins -> 10})]
  ];

markerSymbols[n_] :=
 Drop[Drop[
    ListPlot[Transpose[{Range[n]}], PlotMarkers -> Automatic][[1,
       2]][[1]], -1] /. Inset[x_, i__] :> x, None, -1]

The latter gives you the desired list of automatic colors (but also
the automatic marker symbols that would be needed in ListPlot, in case
you need that).

As an example I'll copy Armand's plot:

stuffToPlot = {Sin[x], Tan[x]};
g = GraphicsGrid[{{Plot[stuffToPlot, {x, 0, 6}],
    Plot[stuffToPlot, {x, 0, 6}]}}, ImageMargins -> {{0, 0}, {30, 0}}]

Here I created some space with ImageMargins to account for the legend,
which is generated now:

Overlay[{g,
  legendMaker[markerSymbols[2][[All, 1]], {"", ""}, stuffToPlot,
   Background -> LightOrange, RoundingRadius -> 10]},
 Alignment -> {Center, Bottom}]

The arguments of the function legendMaker are three lists: line
colors, marker symbols, and text labels. Since there is no need for
marker symbols in this case, I entered the second argument as {"",
""}.

The legend placement is controlled by the Alignment option to Overlay,
and you can see that there are some additional eye-candy options:
Background -> LightOrange, RoundingRadius -> 10

Jens