# Dynamically update a plot of a function that evaluates slowly

Suppose I have a time-consuming function fun[x]. I would like to see the plot between, say {x, 0, 1}. I would like to watch each individual points being plotted as the recursion goes on.

I will use a sin function with a pause to emulate a slow function. In reality, suppose we are plotting a function which is very cost-expensive, thus we want to minimize the total points where the function is evaluated on.

Dynamic2DPlot[fun_, recursion_] :=
Block[{},
plt = {};
list = {{}};
Do[
list = Flatten[{Append[#, 0] & /@ list, Append[#, 1] & /@ list}, 1],
{recursion}];
samples = FromDigits[{#, 0}, 2] & /@ list;
For[j = 1, j <= Length[samples], j++,
coord = samples[[j]];
z = fun[coord];
Pause[0.1];
plt = Append[plt, {coord, z}];];]


samples is just a list of coordinates in the executing order.

{0, 1/2, 1/4, 3/4, 1/8, 5/8, 3/8, 7/8, 1/16, 9/16, 5/16, 13/16, 3/16, 11/16, 7/16, 15/16, ...}

Now this works perfectly, as plt is a global variable

Dynamic[ListLinePlot[SortBy[plt, First], Mesh -> All, PlotRange -> {0, 1}]]
Dynamic2DPlot[Sin[4*#] &, 4] However, putting these two lines in Block or Module will not work, as the Dynamic part ceases to show up. Ideally I'm looking for a way to create a package, where I can call in another notebook like this:

Dynamic2DPlot[fun[x], {x,0,1}, recursion->5]


And it will behave just like a normal ListLinePlot but will update the graph once a new datapoint is calculated.

This might not be an answer because I'm not sure what you're after exactly. It might be CellPrint and CellExpression as shown in the proof-of-concept example below.

slow[x_] := (Pause[0.1]; x (1 - x));
Module[{pts = {}, y, f},
f[x_?NumericQ] := y = slow[x];
CellPrint@ExpressionCell[
Dynamic@ListLinePlot[pts, PlotRange -> {{0, 1}, {0, 1/4}}],
"Output"];
Plot[f[x], {x, 0, 1}, PlotPoints -> 5,
EvaluationMonitor :> (pts = Sort@Append[pts, {x, y}])];
] In this case the plotting is driven by Plot, which has automatic recursive subdivision.

• Thanks a lot! This is very helpful. – Peter Zhang Nov 21 '16 at 19:25

I admit I am not sure about what you trying to do, but the following much simpler code does the same thing as your code does only in a more robust way.

Dynamic2DPlot[fun_, steps_] :=
Do[
plot =
ListLinePlot[{#, fun[#]} & /@ Range[0, 1, 1/2^j],
Mesh -> All, PlotRange -> {-1, 1}];
Pause[.5],
{j, steps}]

plot = Null; Dynamic[plot]
Dynamic2DPlot[Sin[4 #] &, 4]; Whether or not this can serve as the basis of something you can make into a package would more information on how you plan to use the package to decide. However, I believe this to be a far better basis for further exploration of the problem than the code you have posted.

• Thank you, Goldberg. I'm sorry that I didn't make it clear. My goal was to visualize the subdivision as the plot is going on. The pause function is just to emulate a slow function, not just for an animation purpose. So it would be better to reuse the value of a calculated point. Thank you for your help anyway! – Peter Zhang Nov 21 '16 at 19:31