3
$\begingroup$

I have two lists of 2D data I would like to plot on a plane. These lists are of the same length n and are position-correlated to each other.

I need these lists to have two different colors, but share the same symbol for elements at position i in both lists.

For example, in the following image, the points with the same label should share the same symbol.

enter image description here

I have been struggling with ListPlot without success.

EDIT:

Is it possible to have two plot legends? One for the color and another for the symbol?

$\endgroup$

2 Answers 2

3
$\begingroup$

You can plot the datasets separately and combine them with Show:

pts1 = RandomReal[1, {10, 2}];
pts2 = RandomReal[1, {10, 2}];

pl = Show[
 ListPlot[
  List /@ pts1,
  PlotStyle -> ColorData[97, 1],
  PlotMarkers -> plotMarkers
  ],
 ListPlot[
  List /@ pts2,
  PlotStyle -> ColorData[97, 2],
  PlotMarkers -> plotMarkers
  ]
 ]

Example

I used letters for plot markers. You can set PlotMarkers to Automatic to get the default shape. Also have a look here for other options.

For legends, you could do something like this:

legend1 = PointLegend[
  {ColorData[97, 1], ColorData[97, 2]},
  {"Data A", "Data B"}
  ]

legend2 = PointLegend[
  ConstantArray[ColorData[97, 1], 10],
  plotMarkers,
  LegendMarkers -> plotMarkers
  ]

Row[{
  Show[pl, ImageSize -> 400],
  legend1,
  legend2
  }]

Multiple legends

I'm using Row here, you might be needing a different approach to the layout depending on how you want to lay them out.

$\endgroup$
4
  • $\begingroup$ How could I have a legend for both color and markers with this solution? $\endgroup$ Commented May 5, 2020 at 15:43
  • 1
    $\begingroup$ @GuillermoOliver See my update. $\endgroup$
    – C. E.
    Commented May 5, 2020 at 15:57
  • $\begingroup$ Thank you very much! $\endgroup$ Commented May 5, 2020 at 16:00
  • 1
    $\begingroup$ As an alternative, legends can be inserted and placed in the desired position, one per plot, using PlotLegends. No need to use Row, using Show to visualize both plots would be enough. $\endgroup$ Commented May 5, 2020 at 17:00
0
$\begingroup$
Clear["Global`*"];
SeedRandom[99];
pts1 = RandomReal[{-3, 3}, {15, 2}];
pts2 = First@RandomReal[{-1, 1}, {1, 2}] + # & /@ pts1;

pts1labeled = Transpose[{pts1, Alphabet[][[1 ;; Length@pts1]]}];
pts2labeled = Transpose[{pts2, Alphabet[][[1 ;; Length@pts2]]}];

ListPlot[{
  Callout[#1, #2, CalloutStyle -> Red] & @@@ pts1labeled
  , Callout[#1, #2, CalloutStyle -> Blue] & @@@ pts2labeled
  }
 , PlotLegends -> {
   Placed[
    SwatchLegend[
     Automatic, {"1", "2"}]
    , {After, Center}]
   , Placed[Panel[#, Alignment -> Center] &@LineLegend[
      ConstantArray[Black, Length@pts1]
      , Alphabet[][[1 ;; Length@pts1]]
      , LegendLayout -> {"Row", 2}
      ], Below
    ]
   }
 , PlotStyle -> {Red, Blue}
 , PlotRange -> {{-3, 3}, {-3, 3}}
 , PlotRangePadding -> Scaled[.15]
 , ImageSize -> 600
 , Epilog -> {
   Line /@ Transpose[{pts1, pts2}]
   }
 ]

enter image description here

$\endgroup$

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.