# ListPlot and comparisons between lists

The problem is a bit tricky, I will try to be as clear as possible. I have several lists (let's call them x, y, z and k), all of the same length, and where the i-th value of each list corresponds to a single observation (so for instance x[], y[], z[] and k[] are the values of four variables for the third observation). What I want to do is a scatter plot, where the x-axis reports the values of x and the y-axis the values of y. Now, for each pair (x[[i]], y[[i]]) I want a red dot if z[[i]] > k[[i]], and a black dot otherwise. Additional issue: for the first observations, the list k is empty, so I want to plot a red dot for such observations. Any idea on how is it possible to do it?

• Hint: You can style individual points in ListPlot using Style[{x, y}, color]. May 27 '20 at 14:16
• That is very helpful, I will have a try with that. Thank you. May 27 '20 at 14:19

Here is an example with made up data:

Clear[y, z, k]
x = Range;
{y, z, k} = RandomInteger[{-10, 10}, {3, 20}];

ListPlot[
MapThread[Style[{#1, #2}, If[#3 > #4, Red, Black]] &, {x, y, z, k}],
PlotRange -> All,
PlotStyle -> PointSize[0.02]
] For your second part ("Additional issue: for the first observations, the list k is empty, so I want to plot a red dot for such observations."), you should really provide a sample of your data. Any answer would depend on its precise structure.

• That is perfect, thank you! May 27 '20 at 14:30
• For the last part you could just PadLeft the kkkkk... list with some non-number element e.g {} to the same size as any of the the xxxxx... or yyyyy.... zzzzz... lists before transposing to {{x,y,z,{}},{x,y,z,{}},{x,y,z,k},{x,y,z,k}... etc}. Then change your style function to only apply if #4 is not {}. May 27 '20 at 14:33
• Thank you for the added comment, your code actually worked nice as it is :) May 27 '20 at 19:57
• I have an additional question. What if I would like to use different shapes instead of different colours? Jun 5 '20 at 9:21
• @MarcoB can you help me? Jun 7 '20 at 12:11

Generate random data with first two values of k missing.

SeedRandom

{x, y, z, k} =
ReplacePart[RandomReal[{0, 10}, {4, 20}], {{4, 1}, {4, 2}} -> Missing]


Just use Graphics primitives to make the scatter plot.

Legended[Graphics[{AbsolutePointSize[
4], {If[#[] === Missing || #[] > #[], Red, Black],
Point[#[[1 ;; 2]]]} & /@ Transpose[{x, y, z, k}]},
Frame -> True,
FrameLabel -> (Style[#, 14, Bold, Italic] & /@
{"x", "y"} /.
s_String :> Subscript[s, "i"]),
AspectRatio -> 1/GoldenRatio],
PointLegend[{Red, Black}, {"z" > "k", "z" <= "k"} /.
s_String :> Subscript[s, "i"]]] EDIT: Alternatively, you get the same plot using GatherBy with the criteria to generate two data sets.

plotData = #[[All, 1 ;; 2]] & /@
GatherBy[Transpose[{x, y, z, k}], #[] === Missing || #[] > #[] &];

ListPlot[plotData,
PlotStyle -> {Red, Black},
Frame -> True,
FrameLabel -> (Style[#, 14, Bold, Italic] & /@
{"x", "y"} /.
s_String :> Subscript[s, "i"]),
PlotLegends -> {"z" > "k", "z" <= "k"} /.
s_String :> Subscript[s, "i"]]

• I am sorry, I just notice I did not answer you. Thank you for your answer. I just have an additional question: what if I would like to do the same, but using different shapes instead of different colours? Jun 7 '20 at 12:12
• Use the option PlotMarkers, e.g., PlotMarkers -> Automatic Jun 7 '20 at 15:24
• Thank you! I cannot believe it was that easy, I was trying much more complicated stuff. Jun 9 '20 at 7:41