# How to change the filling color under a plot according to a value?

Mathematica has an option to fill the space under a curve with a value:

ListLinePlot[Transpose[data][], Filling -> Axis]


I have a dataset data=$\{\{val_1,class_1\},\{val_2,class_2\},\{val_3,class_3\}\ldots\}$. The values $val_i$ are what is to be plotted while the values $class_i$ are which class the value belongs to.

I would like to be able to change the color of the filling under the curves of values $val_1,val_2,val_3,\ldots$ according to which class $class_1,class_2,class_3,\ldots$ the value belongs to.

For example, $class_1$ would be Blue, $class_2$ would be Red and $class_3$ would be Green...

A numerical example: I have the dataset:

{{0.9,"A"},{1.9,"A"},{1.2,"C"},{1.0,"B"},{2.5,"D"},...}


I want to plot {0.9,1.9,1.2,1.0,2.5} according to their A,B,C,D labels...

Perhaps you mean something like this?

SeedRandom;
classes = {1, 2, 3};
data = Transpose[{Range^2, RandomChoice[classes, 100]}];

ListPlot[classes /.
GroupBy[MapIndexed[First /@ {#2, #1} &, data], data[[First@#, 2]] &],
Filling -> Axis, FillingStyle -> Thick] Alternate solution

dataIF = Interpolation[data[[All, 1]], InterpolationOrder -> 1];
cf[class_] := class /. {1 -> Blue, 2 -> Red, 3 -> Green};

ParametricPlot[{x, t dataIF[x]}, {x, 1, 100}, {t, 0, 1},
Mesh -> {Range[0, 100] + 1/2}, MeshFunctions -> {#1 &},
MeshStyle -> None,
MeshShading -> cf /@ data[[All, 2]], AspectRatio -> 1/GoldenRatio] Well, it uses the OP's color suggestions. :)

• I understood something similar, but the OP wants ListLinePlot[], which is problematic because the color of the first (or last) trapezoid is undefined – Dr. belisarius Sep 21 '14 at 20:11
• @belisarius Yes, ListLinePlot may be impossible to use. But before going into it further, I think the question needs clarification about which of the proposed answers, if any, are on target. – Michael E2 Sep 21 '14 at 20:12
• @belisarius Of course, you just gave me another idea... – Michael E2 Sep 21 '14 at 20:21
• Since the OP doesn't react I dare to upvote your answer. – eldo Sep 21 '14 at 20:29
• Well, I can't upvote twice :) – Dr. belisarius Sep 21 '14 at 20:41

Update: Using ColorFunction introduces blending of colors in region boundaries (see the original post below). Two approaches to get clear separation of colors appeared in this related Q/A (1) split the data and overlay separate plots using Show, or (2) construct polygons directly from the data and use them as Prolog. I use the latter method below.

SeedRandom;
classes = {1, 2, 3};
data2 = Transpose[{Range, Range^2, RandomChoice[classes, 100]}];


Michael's color function

cf[class_] := class /. {1 -> Blue, 2 -> Red, 3 -> Green};


and a function to create polygons

epilogF = Partition[#, 2,
1] /. {{t1_, v1_, class_}, {t2_, v2_, _}} :> {c = cf[class],
EdgeForm[c], Polygon[{{t1, 0}, {t2, 0}, {t2, v2}, {t1, v1}}]}&;

Graphics[epilogF[data2], AspectRatio -> 1/GoldenRatio, Axes -> True]
(* or ListLinePlot[data2[[All,;;2]], Epilog -> epilogF[data2]] *) Original post:

Using Michael's example data with three classes

SeedRandom;
classes = {1, 2, 3};
data = Transpose[{Range^2, RandomChoice[classes, 100]}];

intF = Interpolation[Last /@ data, InterpolationOrder -> 0];
ListLinePlot[Transpose[data][], Filling -> Axis,
ColorFunction -> ({Blue, Red, Green}[[intF[#1]]] &), ColorFunctionScaling -> False] Alternatively, you can use a slightly modified version of Michael's cf:

cf2[x_] :=  data[[x, 2]] /. {1 -> Blue, 2 -> Red, 3 -> Green};
ListLinePlot[Transpose[data][], Filling -> Axis, ColorFunction -> (cf2[#1] &),
ColorFunctionScaling -> False] If I understand correctly, you want something like this:

val1 = Array[Sin, 100, {0, 2 Pi}];
class1 = "a";
val2 = Array[Cos, 100, {0, 2 Pi}];
class2 = "b";

data = {{val1, class1}, {val2, class2}};
fillingstyle = Table[i -> {Axis, data[[i, 2]]}, {i, Length@data}]/.{"a" -> Gray, "b" -> Pink};

ListLinePlot[Transpose[data][], Filling -> fillingstyle] 