# Assigning colors to multiple datasets in a ListPlot

I have to generate 10-50 random real numbers:

List[ RandomReal[{-10, 10}, {RandomInteger [{10, 10}]}]]

This I've done, but I also have to make a ListPlot in which numbers from 1 to 10 will be Blue, from 0.99 to -0.99 will be Red and from -1 to 10 will be Green.

I tried to separate the list into 3 sublists. I also tried to use conditions but I can't make it work. Could someone help?

• Have you seen Select[]? Nov 8, 2017 at 11:45
• There should be a solution that uses ColorFunction but I see nothing in the Help. Anyone?
– A.G.
Nov 8, 2017 at 14:09
• @A.G. - For ListPlot, "ColorFunction requires at least one dataset to be Joined", i.e., it will vary the color of a line not points. Nov 8, 2017 at 14:21

rand = RandomReal[{-10, 10}, RandomInteger[{10, 50}]];
bluelist = redlist = greenlist = {};
Which[1 <= # <= 10, AppendTo[bluelist, #],
-1 <  # <   1, AppendTo[redlist, #],
-10 <= # <= -1, AppendTo[greenlist, #]] & /@ rand;
ListPlot[#1, PlotStyle -> #2] & @@
Transpose[DeleteCases[
{{bluelist, Blue}, {redlist, Red}, {greenlist, Green}}, {{}, _}]]


Generate 50 random pairs of data

SeedRandom[10];
data = RandomReal[{-10, 10}, {50, 2}];


SortBy the Last element of each pair and then split into the three groups using SplitBy the Last element

data3 = SplitBy[SortBy[data, Last], Abs[Last@#] > 1 &];


ListPlot the three groups of data

ListPlot[data3, PlotStyle -> {Green, Red, Blue}]


• This breaks with SeedRandom[778]. Nov 8, 2017 at 13:09
• @ChrisDegnen - For RandomSeed[778] there is no data in the range -1 < y < 1 so there is no split thereby resulting in a single color. Nov 8, 2017 at 14:25
• Exactly. Everything from -10 to +10 is coloured green, whereas the positive data points should be blue. Nov 8, 2017 at 14:29
CF = Which[1 <= #2 <= 10, Blue, -1 < #2 < 1, Red, -10 <= #2 <= -1, Green] &;

SeedRandom[10];
data = RandomReal[{-10, 10}, {50, 2}];

options = {Frame -> True, Axes -> False,
GridLines -> {None, {-10, -1, 1, 10}}, PlotRange -> {-11, 11},
ImageSize -> Large};


1. Use CF as the color function setting in ListLinePlot with the options Mesh -> All (to make the points visible) and PlotStyle -> LineOpacity -> 0 (to make lines invisible) and ColorFunctionScaling -> False:

ListLinePlot[data, Mesh -> All, PlotStyle -> LineOpacity -> 0,
ColorFunction -> CF, ColorFunctionScaling -> False, options]


2. Post-process ListPlot output to recolor points using CF:

postProcess = ReplaceAll[Point[x_] :> Point[x, VertexColors -> (CF @@@ x)]];

postProcess @ ListPlot[data, options]


3. Make each point a seperate dataset and use CF to style each dataset:

ListPlot[List /@ data, PlotStyle -> CF @@@ data, options]


4. Wrap each point with Style using CF for styling:

ListPlot[MapThread[Style] @ {data, CF @@@ data},  options]


same picture

Does this help?:

SeedRandom[10, Method -> "MKL"];
data = Transpose[{RandomReal[{-10, 10}, 50],RandomInteger[{-10, 10}, 50]}];
colors = Piecewise[{{RGBColor[1, 0, 0], 1 <= #[[1]] <= 10},
{RGBColor[0, 1, 0], -0.99 <= #[[1]] <= 0.99},
{RGBColor[0, 0, 1], -10 <= #[[1]] <= -1}}] & /@ data;
Graphics[{PointSize[0.02], Point[data, VertexColors -> colors]},
AspectRatio -> 1, Frame -> True]


SeedRandom[10];
data = RandomReal[{-10, 10}, {50, 2}];
d1 = Select[data, Last@# < -1 &];
d2 = Select[data, -1 <= Last@# <= 1 &];
d3 = Select[data, Last@# > 1 &];

p1 = ListPlot[{d1, d2, d3}
, PlotStyle -> {Darker@Green, Red, Blue}
];
p2 = Plot[{1, -1}, {x, -10, 10}
, PlotStyle -> {None, None}
, PlotRange -> {-12, 12}
, Filling -> {
1 -> {Top, LightBlue}
, 2 -> {Bottom, LightGreen}
, 1 -> {{2}, Nest[Lighter, Red, 6]}
}
];

Show[p2, p1]


EDIT Using a ColorFunction is possible for a ListLinePlot as @BobHanlon mentioned in the comments. Assuming that the data2 is a list of 50 random numbers between {-10,10}, here are a few variations:

SeedRandom[10];
data2 = RandomReal[{-10, 10}, 50];
If[# < -1, Style[#, Darker@Green],
If[# > 1, Style[#, Blue], Style[#, Red]]] & /@ data2 // Sort


GraphicsRow[ListLinePlot[#
, ColorFunction ->
Function[{x, y}, If[y < -1, Darker@Green, If[y > 1, Blue, Red]]]
, ColorFunctionScaling -> False
, PlotRange -> {-10, 10}
] & /@ {data2, data2 // Sort}
]