10
$\begingroup$

Is there a cleaner way to apply different styles to the different channels of a multi value interpolation function?

here is a 2-output interpolation function:

f = Interpolation[Table[ {x, N@{Sin[x], Cos[x]}}, {x, 0, 2 Pi, Pi/20}]]

if we just plot it the two functions take the same style

Plot[f[x], {x, 0, 2 Pi}, PlotStyle -> {Red, Blue}]

enter image description here

Here is one way to separately style:

Plot[{f[x][[1]], f[x][[2]]}, {x, 0, 2 Pi}, PlotStyle -> {Red, Green}]

enter image description here

This feels inefficient, apparently this computes both interpolations twice. I also cant figure an incantation to do this without explicitly listing..

Plot[Table[f[x][[i]], {i, 2}], {x, 0, 2 Pi}]

doesn't work.

We can crunch out a table and use ListPlot, but that seems unsatisfactory.

Is there a cleaner way?

$\endgroup$
4
  • $\begingroup$ I vaguely remember similar question where the answer was that Plot sees f[x] as a single object and therefore only recognizes one PlotStyle whereas Plot sees {f[x][[1]],f[x][[2]]} as two objects (as you've discovered). I wish I could remember but it wasn't that long ago and it had a good explanation of the issue. $\endgroup$
    – JimB
    Nov 18, 2016 at 21:50
  • 1
    $\begingroup$ just found this: mathematica.stackexchange.com/q/8637/2079 -- havent gone through to see if anything there works. $\endgroup$
    – george2079
    Nov 18, 2016 at 21:58
  • 2
    $\begingroup$ Mr.Wizard's styleSplitter works as it stands. $\endgroup$
    – corey979
    Nov 18, 2016 at 22:05
  • 1
    $\begingroup$ I can report this: mathematica.stackexchange.com/a/87113/2079 works. I dont think this is quite a duplicate since I hold out hope there is a cleaner method specific the the multi-value interpolation function. $\endgroup$
    – george2079
    Nov 18, 2016 at 22:05

4 Answers 4

7
$\begingroup$

If the sampling is dense enough, as it usually is in NDSolve output, ListLinePlot will do style each curve separately.

ListLinePlot[f]

Mathematica graphics

ListLinePlot[f, PlotStyle -> {Red, Green}]

Mathematica graphics

$\endgroup$
2
  • 2
    $\begingroup$ nice.. the caveat here is ListLinePlot is effectively showing a linear interpolation regardless of the order of the input interpolation. Its also useful to know you can ListPlot this way and readily see the actual solution points coming from NDSolve. Stranegly this doesn't seem to be documented. $\endgroup$
    – george2079
    Nov 20, 2016 at 21:00
  • $\begingroup$ @george2079 Yes, it's connect-the-dots, which is the reason for the condition, "If the sampling is dense enough." Perhaps, I should have been clearer. It can be an advantage over Plot, in terms of speed. BTW, ListLinePlot[.., Mesh -> All] will plot both the graph and the solution points. I don't remember where I learned this, but I use it a lot, most recently here. $\endgroup$
    – Michael E2
    Nov 20, 2016 at 21:58
5
$\begingroup$

As already noted in the comments my styleSplitter will handle this, as will xslittlegrass's restylePlot2. If you are after the simplest possible method (least code) this is the best I can think of at the moment:

Plot[f[x], {x, 0, 2 Pi}] /.
  {d_, x__Line} :> {d, Riffle[{x}, {Red, Blue}, {1, -2, 2}]}

This could be hard-coded for only two Line expressions but Riffle is more general.


It occurs to me that you did not forbid modifying the InterpolatingFunction expression, therefore we could split that in two before plotting:

f1 = MapAt[First, f, {4, All, 1}];
f2 = MapAt[Last,  f, {4, All, 1}];

Plot[{f1[x], f2[x]}, {x, 0, 2 Pi}, PlotStyle -> {Red, Blue}]
$\endgroup$
4
$\begingroup$

In version 9.0, you can also use

Plot[f[x] , {x, 0, 2 Pi}, PlotStyle -> (i = 1; {{Red, Green}[[i++]], #} &)]

Mathematica graphics

$\endgroup$
1
  • $\begingroup$ i can confirm this doesn't work in 10..in fact v10 seems to not like any sort of function for PlotStyle $\endgroup$
    – george2079
    Nov 20, 2016 at 21:05
3
$\begingroup$

Another way is as following: First, lets define a InterpolationFunction with n=30 curves.

    n = 30; f = 
    Interpolation[Table[{x, Table[x^j, {j, 1, n}]}, {x, 2, 5, 10^-3}]]

This LogPlot schows different colors.

    pl2 = LogPlot[
  Evaluate@Table[With[{i = i}, Hold[f[x][[i]]]], {i, n}], {x, 2, 5}, 
  PlotStyle -> Table[Hue[.8 j/n ], {j, 0, n - 1}]] // Timing

Although f has to be evaluated several times, it is even faster than the standard Plot.

    pl3 = LogPlot[f[x], {x, 2, 5}] // Timing

That means, time consumption for the solution pl2 can be neglected.

$\endgroup$
1
  • $\begingroup$ great.. this is effectively building up the list I wrote by hand in the question. Good to know how to do that! $\endgroup$
    – george2079
    Nov 20, 2016 at 21:08

Your Answer

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

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