3
$\begingroup$

I often find myself in a situation where I want to see something animated 'live'. With this I mean I have some data, a function to update that data let's call it step[] and then want to display the data as it updates. I never found a good way to do this.

To make it more clear let's look at an example.

Initialise data:

n = 100;
x = RandomReal[1, n]*.01;
f[x_] := Mod[x 1.01, 1]

Step function:

step[] := Module[{}, x = f[x]]

Display code:

ListPlot[{Cos[2 \[Pi] x], Sin[2 \[Pi] x]}\[Transpose], 
 AspectRatio -> 1, PlotRange -> {{-1, 1}, {-1, 1}}]

enter image description here

After looking at the documentation I could come up with two ways to animate this. In one cell run:

animationRunning = True;
While[animationRunning, step[]; Pause[.1]]

In another run:

Dynamic[ (* display code *) ]

This does what I want but it locks up the interpreter (I can't run another cell) and it feels like it's not the intended way to animate because it doesn't make use of the functions intended for animation.

Another way I found is to run this in one cell:

Dynamic[Refresh[step[], UpdateInterval -> 2]]

and run Dynamic[ (* display code *) ] in another cell again. This behaves better than the while loop but it completely ignores the UpdateInterval: it just runs as fast as it can. I want some control over the speed.

So is there any proper way to do these kinds of animations?


Based on MassDefect's answer I was finally to make what I wanted

Here's the code

Animate[step[]; a;, {a, Infinity}, RefreshRate -> 3]

Dynamic[ListPlot[{Cos[2 \[Pi] #], Sin[2 \[Pi] #]}\[Transpose] &@x, 
  AspectRatio -> 1, PlotRange -> {{-1, 1}, {-1, 1}}]]

Benefits of this code

  • Easy to pause/unpause
  • Controllable speed
  • Arbitrarily complex code in the step[] function
  • Runs in real time (not predefined like ListAnimate)
$\endgroup$
4
  • 2
    $\begingroup$ What are you trying to accomplish? Like do you eventually want to export the animation or something? An animation that runs forever will inevitably either lock up the front end or continuously return focus to that cell. If you run a new piece of code in between updates, the update will end up being delayed unless you run them on separate kernels. $\endgroup$ – MassDefect Jan 12 at 19:40
  • $\begingroup$ I just want to look at the animation. I suspect it is still possible because functions like Animate[] or Animator[]almost do what I want but those functions only work for animations that are parametrised by some variable and don't run continuously. I'm used to there being some kind of animation-loop like FuncAnimation in Python (Matplotlib) or RequestAnimationFrame in Javascript and I can't find such a function in Mathematica. $\endgroup$ – AccidentalTaylorExpansion Jan 13 at 10:57
  • $\begingroup$ Look at your code ListPlot[{Cos[2 \[Pi] x], Sin[2 \[Pi] x]}\[Transpose]... ListPlottakes a list, not a function. The Transpose does nothing. $\endgroup$ – Daniel Huber Jan 13 at 11:11
  • $\begingroup$ @DanielHuber I think that's an artefact from copying code to stack exchange. You should read it as Transpose[ { Cos[ 2 pi x ], Sin[ 2 pi x ] } ]. In Mathematica it's a superscript T. The transpose is necessary to make the code work though. $\endgroup$ – AccidentalTaylorExpansion Jan 13 at 22:10
3
$\begingroup$

Here's a way to use Animate:

n = 100;
x := RandomReal[1, n];
Animate[
  ListPlot[
    a;
    {Cos[2 \[Pi] #], Sin[2 \[Pi] #]}\[Transpose] &@x,
    AspectRatio -> 1,
    PlotRange -> {{-1, 1}, {-1, 1}}
  ],
  {a, Infinity},
  RefreshRate -> 5
]

The RefreshRate is in frames per second. By changing the definition of x from = to := a new set of random numbers is generated every time you call x. Make sure to only call x (or your step function or whatever) once. If you make separate calls to it for both Cos and Sin, you'll get a different set of random numbers for each.

Intensive computations may slow down the animation. I'm not sure that there's a way around unless you can have two different front-end kernels running in one notebook. I don't know enough about that to say whether you can or not.

The refresh rate in the gif below doesn't correspond with the one I set in the notebook because you need to independently specify "DisplayDurations" during Export and I forgot to.

enter image description here

$\endgroup$
2
  • $\begingroup$ This doesn't do exactly what I want but this gave me the tools to make it work. Didn't know that you could pass Infinity to the animator. $\endgroup$ – AccidentalTaylorExpansion Jan 13 at 21:57
  • $\begingroup$ Thanks for the help! $\endgroup$ – AccidentalTaylorExpansion Jan 13 at 22:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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