# Change order of evaluation in Plot[] nested with NDSolve[]

I noticed that in Plot the function is evaluated at each sample point

Plot[func@x,{x,rStart1,rEnd1}]


which is fine for a regular function. If I substitute the function with an NDSolve, the problem is that at every sample point the NDSolve is evaluated so it is time consuming.

Plot[NDSolve[(*diff equation*)][[1]]@x,{x,rStart1,rEnd1}]


I find a workaround to NDSolve only once, and pass it to the Plot[].

NDSolve[(*diff equation*)][[1]] //Plot[#@x, {x, rStart1, rEnd1}] &


I just wonder if there is a better way to do it, for example to Hold/Release or some magical trick to force it only being evaluated once.

• possibly of interest: Plotting the sum of curves without recalculation. Commented Feb 9, 2018 at 15:19
• Indeed it is interesting. Thanks! Commented Feb 9, 2018 at 16:44
• Commented May 29, 2018 at 19:57

Two alternatives that would evaluate only once.

Let's verify that by using a counter

counter = 0;
Dynamic[counter]


## With

With[
{
func = NDSolve[
counter += 1;
{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}
, y
, {x, 0, 30}
][[1, 1, 2]]
},
Plot[
func[x]
, {x, 0, 30}
, PlotRange -> All]
]


## Evaluate

Plot[
Evaluate[
y[x] /. NDSolve[
counter += 1;
{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}
, y
, {x, 0, 30}
]]
, {x, 0, 30}
, PlotRange -> All
]


Perhaps the easiest way in V9+ is

ListLinePlot@ NDSolve[(*ode for y[x]*), y, x]


Example from @rhermans:

ListLinePlot@
NDSolveValue[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, 30}]