One of my favorite things about Processing is that you can interact with a simulation while it is running. Here is an example where a swarm of particles are advecting continually in a flow, and changing the shape of the foil changes the underlying velocity field. It’s great for education and outreach activities.
Observables in Makie and Pluto seem tantalizingly close to realizing this capability, but I haven’t seen this done anywhere and my attempt today failed. Are there some examples of this I’ve missed? Any ideas for where to start?
4 Likes
I only very quickly looked at Processing - as far as I have seen their central point is that the draw()
function is executed automatically in short time intervals.
In Pluto you could archive this with a GitHub - JuliaPluto/PlutoUI.jl Clock element:
@bind tick PlutoUI.Clock(interval=0.001)
begin
tick
draw()
end
3 Likes
Can the clock element animate moving a slide element?
The clock element just triggers execution of the cells where its @bind
variable is referenced in regular intervals. The rest needs to be implemented in these cells.
This works, but it is quite slow (framerate around 1). This is probably because I’m not updating the plots as efficiently as I could. If you know of any examples using this to update large plots quickly, I’ll take another look next week.
Sorry, but it seems there has been a change and this no longer works?
@bind tick PlutoUI.Clock(interval=0.001)
Failed to show value:
UndefVarError: interval not defined
Any idea what’s going on?
Strange, it works for me:
Edit: I am using Pluto v0.12.21 and PlutoUI 0.7.6.
I guess it was a version thing. I just updated to those (most recent) versions and it works again.
Sorry to keep bugging on this, but I have one more question.
The clock
works great to repeatedly call a mutating function step!(sim)
. However, every time I update a parameter of sim
using a slider, Pluto automatically reinitializes the strut. That’s a great default behavior, but is there a way to tell Pluto how to mutate the struct instead of reinitializing? I would like it to call a specific function, say update!(sim)
, instead of calling the initial sim=Simulation(...)
function again.
You could wrap the struct into a Ref to prevent automatic updates, see Zulip
Edit: Paste from Zulip:
also consider defining a Ref in a separate cell, which never reruns (because it has no dependencies):
did_the_thing = Ref(false)
Use it like so:
if condition && !did_the_thing[]
did_the_thing[] = true
# code that should run only once
end
Zulip? Sigh. Why not? This is like the 40th chat/stream/channel thing I’m on now…
That didn’t work, but I’ve posted the question on zulip (sigh) and will report back.