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$

3 Answers 3

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$
5
  • $\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$ Sep 21, 2014 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, 2014 at 20:12
  • $\begingroup$ @belisarius Of course, you just gave me another idea... $\endgroup$
    – Michael E2
    Sep 21, 2014 at 20:21
  • $\begingroup$ Since the OP doesn't react I dare to upvote your answer. $\endgroup$
    – eldo
    Sep 21, 2014 at 20:29
  • $\begingroup$ Well, I can't upvote twice :) $\endgroup$ Sep 21, 2014 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$
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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.