2
$\begingroup$

If I create a ListPlot with several datasets Mathematica will automatically attribute plotmarker colours to the data from each set.

xydata1 = Transpose@{Table[RandomReal[{50, 10}], 10], 
                     Table[RandomReal[{3, 11}], 10]};
xydata2 = Transpose@{Table[RandomReal[{50, 10}], 10], 
                     Table[RandomReal[{3, 11}], 10]};
xydata3 = Transpose@{Table[RandomReal[{50, 10}], 10], 
                     Table[RandomReal[{3, 11}], 10]};


 data = {xydata1, xydata2, xydata3};

 ListPlot[
  data,
  PlotMarkers -> Automatic,
  Frame -> True,
  FrameLabel -> {"x-axis label", "y-axis label"},
  PlotLegends -> Placed[{"data1", "data2", "data3"}, Below]
 ]

enter image description here

Now, if I want to split up these data so that they are plotted in different groups. E.g.

xylabels = {"data1", "data2", "data3"};
xylabmix = {{"data1", "data2"}, {"data2", "data3"}, {"data1","data3"}};
datamix = {{xydata1, xydata2}, {xydata2, xydata3}, {xydata1, xydata3}};

dataplot[xy_, label_] := ListPlot[
  xy,
  PlotMarkers -> Automatic,
  Frame -> True,
  FrameLabel -> {"x-axis label", "y-axis label"},
  PlotLegends -> Placed[label, Below]
  ]

GraphicsGrid[{MapThread[dataplot[#1, #2] &, {datamix, xylabmix}]}, 
 ImageSize -> 600]

enter image description here

The question is how can I keep the same PlotMarker attributes so that all the colours and symbols are retained by each dataset in subsequent plots?

Is it necessary to explicitly define the PlotMarker and PlotStyle attributes of each dataset? If so, what would be an effective way to apply these attributes assuming a larger number of datasets (>20)?

Are there questions/answers that already address this? (I had a bit of a search but couldn't find much that was applicable).

$\endgroup$
1
$\begingroup$

This should get you started:

SeedRandom[123];

(* original code *)

xydata1 = 
  Transpose@{Table[RandomReal[{50, 10}], 10], 
    Table[RandomReal[{3, 11}], 10]};
xydata2 = 
  Transpose@{Table[RandomReal[{50, 10}], 10], 
    Table[RandomReal[{3, 11}], 10]};
xydata3 = 
  Transpose@{Table[RandomReal[{50, 10}], 10], 
    Table[RandomReal[{3, 11}], 10]};


data = {xydata1, xydata2, xydata3};
xylabels = {"data1", "data2", "data3"};

Create some subsets:

subs = Subsets[Range[Length[data]], {2}];

Now map the subsets onto your plot function:

GraphicsGrid[{
  ListPlot[Part[data, #],
     PlotMarkers -> Automatic,
     Frame -> True,
     PlotStyle -> (# /. ColorData[97, "ColorRules"]),
     FrameLabel -> {"x-axis label", "y-axis label"},
     PlotLegends -> Placed[Part[xylabels, #], Below]
     ] & /@ subs
  },
 ImageSize -> 600]

enter image description here

Edit

Forgot the plot markers:

GraphicsGrid[{
  ListPlot[Part[data, #],
     PlotMarkers -> Part[Graphics`PlotMarkers[], #],
     Frame -> True,
     PlotStyle -> (# /. ColorData[97, "ColorRules"]),
     FrameLabel -> {"x-axis label", "y-axis label"},
     PlotLegends -> Placed[Part[xylabels, #], Below]
     ] & /@ subs
  },
 ImageSize -> 600]

enter image description here

$\endgroup$
0
1
$\begingroup$

Update:

colors = ColorData[97, "ColorList"][[;;3]];
sizes = 10;
markers = ChartElementData["SimpleMarkers"][[;; 3, 1]];
coloredmarkers = Graphics[{#, #2[[1]]}, ImageSize -> #3] &@@@ 
  Thread[{colors, markers, sizes, labels}];
labels = {"data1", "data2", "data3"};
legendeddata = Legended[#, Placed[#2, Below]]& @@@ Transpose[{data, labels}];

ListPlot[legendeddata[[#]], ImageSize -> 300,
   PlotMarkers -> coloredmarkers[[#]]] & /@ 
    Rest[Subsets[Range[3], 2]] // Partition[#, 3, 3, 1, {}]& // Grid

enter image description here

Original answer:

ClearAll[dropF]
dropF[k_] := Module[{ml = (LegendMarkers /. Options[#[[2,1]], LegendMarkers])[[All,1]]}, 
  # /.  {If[Head[ml[[k]]] === String, ml[[k]] -> "", ml[[k, 1, 1]] -> Nothing], 
   PointLegend[cols_, labels_, HoldPattern[LegendMarkers -> lmarkers_], rest___]:>
    PointLegend[Drop[cols, {k}], Drop[labels, {k}],
     LegendMarkers -> Drop[lmarkers, {k}], rest]}]&;

Examples:

lp1 = ListPlot[data, PlotMarkers -> {Automatic, 20}, Frame -> True, 
 FrameLabel -> {"x-axis label", "y-axis label"}, 
 PlotLegends -> Placed[{"data1", "data2", "data3"}, Below]]

enter image description here

Row[dropF[#][lp1]& /@ {3,2,1}]

enter image description here

markers = ChartElementData["SimpleMarkers"][[All, 1]];
lp2 = ListPlot[data, PlotMarkers -> Thread[{markers, .07}], Frame -> True, 
 FrameLabel -> {"x-axis label", "y-axis label"}, 
 PlotLegends -> Placed[{"data1", "data2", "data3"}, Below]]

enter image description here

Row[dropF[#][lp2]& /@ {3,2,1}]

enter image description here

$\endgroup$
2
  • $\begingroup$ This really two seperate answers. Perhaps you should split it. $\endgroup$ – geordie Feb 2 '18 at 10:44
  • $\begingroup$ @geordie, good point. $\endgroup$ – kglr Feb 2 '18 at 13:09

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.