# Refresh plot during heavy calculations

I have some heavy calculations with generates huge list of {x, y} points. I want to dynamically update plot during calculations. Or update it after calculations complete. I can't use simple Dynamic @ Plot, because it makes calculation time 5-10x times longer. So I made some example, how I tried to solve this problem. But it didn't work.

Manipulate[None,
Grid[
{{Dynamic[
ListPlot[
Refresh[pts, UpdateInterval -> 5],
PlotRange -> All],
UpdateInterval -> 2],
SpanFromLeft,
SpanFromLeft},
{Slider[Dynamic[a], {10, 20, 1}],
Dynamic@ProgressIndicator[i, {1, a}],
Button["Run", func[], Method -> "Queued"]}}],
TrackedSymbols :> {},
ContinuousAction -> False,
SynchronousUpdating -> False, LocalizeVariables -> True,
Initialization :> (
pts = {{0, 0}}; a = 10; i = 1;
func[] :=
Module[{},
For[i = 1;, i < a, i++, Pause[.5]; AppendTo[pts, {i, i}]]])]


So how can I refresh plot only every n seconds? Or refresh after all calculations complete?

• Can't you just run the plot at the end of the notebook? Jun 26, 2016 at 18:13
• ListPlot[] has to do a lot of fancy stuff. If you just need a graphical monitor, go raw: Graphics[Point[pts], Axes -> True]. Jun 26, 2016 at 21:03

## 3 Answers

Your Manipulate expression works for me when I change your button specification to

Button["Run", pts = {{0, 0}}; func[], Method -> "Queued"]


However, I think it would better to replace your unnecessarily complicated Manipulate expression with a simple DynamicModule expression.

DynamicModule[{pts = {{0, 0}}, a = 10, i = 1, func},
func[] := Do[Pause[.5]; AppendTo[pts, {i, i}], {i, a}];
Dynamic @ Grid[
{{ListPlot[pts, PlotRange -> All], SpanFromLeft, SpanFromLeft},
{Slider[Dynamic[a], {10, 20, 1}],
ProgressIndicator[i, {1, a}],
Button["Run", pts = {{0, 0}}; func[], Method -> "Queued"]}}]]


• U don't explain how can i fix my problem. U didn't use update interval in your example. Finger Down. Jun 29, 2016 at 6:50

Option 1: Use the UpdateInterval option to Dynamics, i.e.,

Dynamic[Plot[...],UpdateInterval->n,TrackedSymbols->{}]


where n is measure in seconds. Here, UpdateInterval is how often Dynamic "manually" updates the expression. By default it will also update it any time one of the symbols is changed, so you also need to set TrackedSymbols->{}.

Option 2: Use a dummy dataset in the Dynamics function, and only update that variable at the desired pace. For example,

Print[Dynamic[Plot[dummyData,...]]]; ...calculation code...; dummyData=newData;

• I updated this answer to reflect the issue Wjx pointed out. Jun 27, 2016 at 5:49
• When i used Option 1: Dynamic[ListPlot[pts, PlotRange -> All], UpdateInterval -> 2, TrackedSymbols -> {}] Plot is always empty. It doen't refresh. Option 2 can work, but not good because of huge variables. Memory is limited. But thx. Jun 29, 2016 at 6:57
• I just doubled checked with the code from your comment, and it works for me. Did you try it without Dynamic? Did you try it with both UpdateInterval and TrackedSymbols removed. Are you sure pts is good data, so that ListPlot[pts] works? Jun 29, 2016 at 21:34

Though similar to @Jess's answer, I think this will work as you want.

Dynamic[PLOT,UpdateInterval->10,TrackedSymbols->{}]


Because UpdateInterval only set the Max Update interval!! So as your data is updating at a almost crazy speed, the plot will sense the change of your data and update crazily as well. You have to manually tell Dynamic: don't track data, simply follow the UpdateInterval!!!

Hope this can help u.

• Yea, this is tweak is necessary. Hope you don't mind I update my answer. Jun 27, 2016 at 5:46
• @JessRiedel Don't mind at all~
– Wjx
Jun 27, 2016 at 7:06