3
$\begingroup$

I'm having some trouble with TableForm in a plot inset (see image).

enter image description here

1) The point markers are under/above the line markers (but I noticed that always the case also in the plots themselves, which is a bit annoying).

2) Is there a way of having "Head1" aligned with the text of the first column instead of with the markers? (in the code I added blank spaces for "manually aligning" them)

3) The most annoying bit: why the first column is not aligned with the second column? "test1" and "test3" are below the lines of "test2" and "test4"

See below the example the code I used for generating the plot:

a = Exp[-#^2] & /@ Range[-5, 5, 0.1];
b = Exp[-(# + 2)^2] & /@ Range[-5, 5, 0.1];

plot = Show[
  ListPlot[
   {a, b},
   PlotRange -> All,
   PlotStyle -> {Directive[Red, Thickness[0.003]], 
     Directive[Blue, Thickness[0.003], Dashed]}
   , PlotMarkers -> {{\[FilledCircle], 14}, {\[FilledSquare], 16}}]

  ,
  ListPlot[
   {a, b},
   PlotRange -> All,
   PlotStyle -> {Directive[Red, Thickness[0.003]], 
     Directive[Blue, Thickness[0.003], Dashed]}
   , Joined -> True,
   InterpolationOrder -> 2],

  Epilog -> {Inset[TableForm[
      {
       {LineLegend[{Red}, {"test1"}, LabelStyle -> {Black, 16}, 
         LegendMarkers -> {\[FilledCircle], 15}, 
         LegendMarkerSize -> 30], Style[Text["test2"], Black, 16]},
       {LineLegend[{Directive[Blue, Dashed]}, {"test3"}, 
         LabelStyle -> {Black, 16}, 
         LegendMarkers -> {\[FilledSquare], 18}, 
         LegendMarkerSize -> 30], Style[Text["test4"], Black, 16]}
       }, 
      TableHeadings -> {None, {Style[Text["         Head1"], Black, 
          16], Style[Text["Head2"], Bold, Black, 16]}}
      , TableSpacing -> {0, 2}
      ],
     Scaled[{0.8, 0.6}]
     ]},

  Frame -> True, FrameStyle -> Black, 
  LabelStyle -> {Black, FontSize -> 20},
  ImageSize -> Large
  ]
$\endgroup$
3
$\begingroup$

You can use a LineLegend with a custom layout

ClearAll[ gridLegend]
gridLegend[headers_List, labels_List, o1 : OptionsPattern[]][colors_, 
    o2 : OptionsPattern[]] :=  Module[{grid}, 
  grid[pairs_] := Grid[{Prepend[headers, ""], ## & @@ 
      Transpose[Prepend[labels, pairs[[All, 1]]]]}, o1, 
    Alignment -> Center, Dividers -> {False, {False, True}}];
  LineLegend[colors, ConstantArray["", Length @ colors], 
   LegendLayout -> grid, o2, LegendMarkers -> {Automatic, 18}, 
   LegendMarkerSize -> {30, 20}]]

Examples:

headers = Style[#, 16] & /@ {"Head1", "Head2"};
colors = {Red, Directive[Blue, Dashed]};
labels = "test" <> ToString[#] & /@ Range[Length[colors] Length[headers]];
labelmatrix = Transpose @ ArrayReshape[Style[#, 16] & /@ labels, 
   {Length @ colors, Length @ headers}];
gridLegend[headers, labelmatrix][colors]

enter image description here

Change colors2 = {Red, Directive[Blue, Dashed], Green}; in place of colors above to get

enter image description here

Useheaders2 = Style[#, 16] & /@ {"Head1", "Head2", "Head3"}; in place of header above to get

enter image description here

Use a 3X3 label list with colors2 and headers2:

enter image description here

Use as PlotLegends:

ListPlot[{a, b}, Joined -> True, PlotRange -> All, 
 PlotStyle->{Directive[Red, Thickness[0.003]], Directive[Blue, Thickness[0.003], Dashed]},
 PlotMarkers -> {{\[FilledCircle], 14}, {\[FilledSquare], 16}}, 
 Frame -> True, 
 PlotLegends -> Placed[gridLegend[headers, labelmatrix][Automatic], Scaled[{0.8, 0.6}]]]

enter image description here

Use with Legended and Show:

show = Show[ListPlot[{a, b}, PlotRange -> All, 
  PlotStyle->{Directive[Red, Thickness[.003]], Directive[Blue, Thickness[.003], Dashed]},
  PlotMarkers -> {{\[FilledCircle], 14}, {\[FilledSquare], 16}}], 
 ListPlot[{a, b}, PlotRange -> All, 
  PlotStyle->{Directive[Red, Thickness[.003]], Directive[Blue, Thickness[.003], Dashed]},
  Joined -> True, InterpolationOrder -> 2], Frame -> True, FrameStyle -> Black, 
  LabelStyle -> {Black, FontSize -> 20}, ImageSize -> Large]; 
Legended[show, Placed[gridLegend[headers, labelmatrix][{Red, 
    Directive[Dashed, Blue]}, LegendMarkerSize -> {70, 30}], Scaled[{0.8, 0.6}]]]

enter image description here

Alternatively, define a custom layout function using TableForm to be used as LegendLayout option setting:

ClearAll[tableLayout]
tableLayout[headers_List, labels_List][pairs_] := 
 TableForm[Transpose[Prepend[labels, pairs[[All, 1]]]], 
  TableHeadings -> {None, Prepend[headers, ""]}, TableAlignments -> Center]

Example:

LineLegend[{Red, Blue}, {"", ""}, LegendLayout -> tableLayout[headers, labelmatrix], 
 LabelStyle -> {Black, 16}, LegendMarkers -> {Automatic, 18}, LegendMarkerSize -> 30]

enter image description here

$\endgroup$
  • $\begingroup$ what to say.. thanks, that's very very useful :) $\endgroup$ – Fraccalo May 23 '18 at 23:52
  • $\begingroup$ @Fraccalo, thank you for the accept. $\endgroup$ – kglr May 23 '18 at 23:55
  • $\begingroup$ I modded a tiny bit the first function you proposed, so that it's more suitable to my purposes: I added some space between lines and columns, and there is the option for manually give the markers (see comment below) $\endgroup$ – Fraccalo May 24 '18 at 7:35
  • $\begingroup$ ClearAll[gridLegend] gridLegend[headers_List, labels_List, markers_: {Automatic, 18}, o1 : OptionsPattern[]][colors_, o2 : OptionsPattern[]] := Module[{grid}, grid[pairs_] := Grid[{Prepend[headers, ""], ## & @@ Transpose[Prepend[labels, pairs[[All, 1]]]]}, o1, Alignment -> Center, Dividers -> {False, {False, True}}, Spacings -> {2, 1.2}]; LineLegend[colors, ConstantArray["", Length@colors], LegendLayout -> grid, o2, LegendMarkers -> markers, LegendMarkerSize -> {30, 20}]] $\endgroup$ – Fraccalo May 24 '18 at 7:35

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.