# An elegant way to plot a numeric function that returns a list, and have each element in a different color

I have a function that takes a numeric argument and returns a list of numbers. I want to plot each element of the list in a different color.

If I use this command,

Plot[f[x],{x,-1,1}]


all the elements are plotted in the same color. The function takes only a numeric argument (its definition is f[x_?NumericQ]:=...) so I can't use Evaluate like in this question.

So far I've been using this command:

Plot[{f[x][[1]],f[x][[2]],f[x][[3]],f[x][[4]]},{x,-1,1}]


Which works fine (since the function evaluates very fast, I don't mind there are redundant evaluations here, see this question). However this is not very elegant, and considering I have 16 elements to plot, it gets downright ugly.

Is there a more elegant way to plot each element in a different color?

-
How about Plot[Evaluate[f[x]], ...]? –  wxffles Nov 14 '12 at 19:08
@wxffles if you have f[x_?NumericQ]:=... (as indicated in the question) then that doesn't work. –  acl Nov 14 '12 at 19:19
@acl Wait... We're actually expected to read the questions now? –  wxffles Nov 14 '12 at 19:23
Identical question asked prior to mathematica.SE existence. –  Sasha Nov 14 '12 at 19:29
@Sasha - in the question you linked to the problem is to avoid redundant evaluations of the function, since it is expensive to evaluate (just like in this question, which is already mentioned above). In my question I don't mind redundant evaluations, my problem is coding style. These are two different issues. –  Joe Nov 15 '12 at 8:27

This seems to work:

With[{n = Length@f[0]},
Plot[Evaluate[Hold[f[x][[#]]] & /@ Range[n]], {x, 0, 1}]]

-
Interesting, Hold is invisible to Plot. +1 –  Rojo Nov 14 '12 at 20:22

PlotStyle settings as functions

With @acl's example function

 f[x_?NumericQ] := {x, x^2, Sin@x, Cos@x, ArcTan[x]}

i = 1;
Plot[f[x], {x, -Pi, Pi},
PlotStyle -> ({Thick, {Red, Green, Blue, Orange,Brown}[[i++]], {##}} &)]


or, a variation:

i = 1;
Plot[f[x], {x, -Pi, Pi}, PlotStyle ->
({Thick, ColorData[5, "ColorList"][[;; Length[f[1]]]][[Mod[i++,Length[f[1]], 1]]],
Arrow @@@ {##}} &)]


Update: ... or use DownValues of the function:

 Plot[Evaluate@DownValues[f][[All, 2]], {x, -Pi, Pi},  PlotStyle -> Thick]


-
This is very cool! But I think it fails if your functions get discontinuous. Try with 1/x}. +1 –  Rojo Nov 14 '12 at 20:14
@Rojo, this trick is still a new discovery for me, so it has many gaps. I think the case you mention can be adressed partially using something like Mod[i++, Length[f[1]], 1] instead of i++ as the part index, bu then you get the two parts of 1/x colored differently. –  kguler Nov 14 '12 at 20:26
Using the downvalues isn't a robust solution, because it completely disregards additional caveats to the definitions. For example, plot: Clear@f;f[x_?NumericQ] /; x < 0 := -{x, x^2, Sin@x, Cos@x, ArcTan[x]} f[x_?NumericQ] := {x, x^2, Sin@x, Cos@x, ArcTan[x]} –  rm -rf Nov 15 '12 at 2:08
@rm-rf, oops -- It did feel too clean to be robust.(I was trying to remove the condition ?NumericQ from the DownValues when I bumped into this.) thanks. –  kguler Nov 15 '12 at 3:01
Incidentally this is essentially the same method Simon Woods posted here: (8644) –  Mr.Wizard Apr 27 '14 at 20:58

This is horrendous, but:

f[x_?NumericQ] := {x, x^2, Sin@x, Cos@x, ArcTan[x]}
length = Length@f[0];
Show@Table[
Plot[f[x][[i]], {x, -1, 1},
PlotStyle -> {ColorData["SunsetColors"][i/length]}],
{i, 1, length}
]


-
f[x_?NumericQ] := {x, x^2, Sin@x, Cos@x, ArcTan[x], ArcCos[x],
x^3/3, -x + 4/x}


And now

Block[{Plot, Part, x},
Plot[f[x]~Part~# &~Array~8, {x, 0, 1}]
]


or

Plot[If[x \[Element] Reals, f[x][[#]]] &~Array~8, {x, 0, 1},
Evaluated -> True]


Using what @wxffles just showed us in his answer

Plot[Hold@f[x][[#]] &~Array~8, {x, 0, 1}, Evaluated -> True]


Stealing @kguler's idea but impelmenting it more manually

Module[{i = 0},
Plot[f[x], {x, 0, 1}] /.
l_Line :> {ColorData[1, "ColorList"][[++i]], l}]

-
Infix with part for no good reason –  Rojo Nov 14 '12 at 20:08

You have to trick mma in thinking that your subsequent datapoints are separate datasets to be able to use PlotStyle with multiple colors.

Dummy data:

vals = Range[0, 2 \[Pi], 1/6 \[Pi]];
results = Sin[#] & /@ vals;


Getting this data in a the right format:

data = Partition[Transpose[{vals, results}], 1];


Then it's just making a rule for the colors and plot the whole thing:

ListPlot[data,
PlotStyle ->

By using ListPlot you're not taking advantage of the adaptive sampling algorithm of Plot. –  Joe Nov 15 '12 at 8:52