2
$\begingroup$

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

ListLinePlot[Transpose[data][[1]], 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...

$\endgroup$
1
$\begingroup$

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][[1]], Filling -> fillingstyle]

Mathematica graphics

$\endgroup$
3
$\begingroup$

Perhaps you mean something like this?

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

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

Mathematica graphics


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]

Mathematica graphics

Well, it uses the OP's color suggestions. :)

$\endgroup$
  • $\begingroup$ I understood something similar, but the OP wants ListLinePlot[], which is problematic because the color of the first (or last) trapezoid is undefined $\endgroup$ – Dr. belisarius Sep 21 '14 at 20:11
  • $\begingroup$ @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. $\endgroup$ – Michael E2 Sep 21 '14 at 20:12
  • $\begingroup$ @belisarius Of course, you just gave me another idea... $\endgroup$ – Michael E2 Sep 21 '14 at 20:21
  • $\begingroup$ Since the OP doesn't react I dare to upvote your answer. $\endgroup$ – eldo Sep 21 '14 at 20:29
  • $\begingroup$ Well, I can't upvote twice :) $\endgroup$ – Dr. belisarius Sep 21 '14 at 20:41
2
$\begingroup$

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[1];
classes = {1, 2, 3};
data2 = Transpose[{Range[100], Range[100]^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]] *)

enter image description here


Original post:

Using Michael's example data with three classes

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

intF = Interpolation[Last /@ data, InterpolationOrder -> 0];
ListLinePlot[Transpose[data][[1]], Filling -> Axis,
   ColorFunction -> ({Blue, Red, Green}[[intF[#1]]] &), ColorFunctionScaling -> False]

enter image description here

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][[1]], Filling -> Axis, ColorFunction -> (cf2[#1] &), 
 ColorFunctionScaling -> False]

enter image description here

$\endgroup$

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.