# 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[[3]], y[[3]], z[[3]] and k[[3]] 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]. – C. E. May 27 at 14:16
• That is very helpful, I will have a try with that. Thank you. – Plastic Man May 27 at 14:19

Here is an example with made up data:

Clear[y, z, k]
x = Range[20];
{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! – Plastic Man May 27 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 {}. – flinty May 27 at 14:33
• Thank you for the added comment, your code actually worked nice as it is :) – Plastic Man May 27 at 19:57
• I have an additional question. What if I would like to use different shapes instead of different colours? – Plastic Man Jun 5 at 9:21
• @MarcoB can you help me? – Plastic Man Jun 7 at 12:11

Generate random data with first two values of k missing.

SeedRandom[1234]

{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[#[[4]] === Missing || #[[3]] > #[[4]], 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}], #[[4]] === Missing || #[[3]] > #[[4]] &];

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? – Plastic Man Jun 7 at 12:12
• Use the option PlotMarkers, e.g., PlotMarkers -> Automatic – Bob Hanlon Jun 7 at 15:24
• Thank you! I cannot believe it was that easy, I was trying much more complicated stuff. – Plastic Man Jun 9 at 7:41