0
$\begingroup$

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?

$\endgroup$
  • 1
    $\begingroup$ Hint: You can style individual points in ListPlot using Style[{x, y}, color]. $\endgroup$ – C. E. May 27 at 14:16
  • $\begingroup$ That is very helpful, I will have a try with that. Thank you. $\endgroup$ – Plastic Man May 27 at 14:19
4
$\begingroup$

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]
]

formatted points


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.

| improve this answer | |
$\endgroup$
  • $\begingroup$ That is perfect, thank you! $\endgroup$ – Plastic Man May 27 at 14:30
  • $\begingroup$ 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 {}. $\endgroup$ – flinty May 27 at 14:33
  • $\begingroup$ Thank you for the added comment, your code actually worked nice as it is :) $\endgroup$ – Plastic Man May 27 at 19:57
  • $\begingroup$ I have an additional question. What if I would like to use different shapes instead of different colours? $\endgroup$ – Plastic Man Jun 5 at 9:21
  • $\begingroup$ @MarcoB can you help me? $\endgroup$ – Plastic Man Jun 7 at 12:11
2
$\begingroup$

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"]]]

enter image description here

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

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.