Hi everyone!
I recently used WGLMakie animations in a Pluto notebook for my Habilitation defense. I thought it was really cool so I want to highlight this possibility by making a Pluto “featured notebook”. Here is a comment and a question.
Comment
I started with the instructions given by this discourse topic. However, it turns out that Bonito is not needed (at least in all cases I checked). In fact, you just have to encapsulate your code snippet into a begin ... end block (or a let ... end block if you want local scope variables so that you can reuse the fig variable name across several animations).
Question
Across multiple tests, it seems that each time you run/restart a notebook, the first animation is bugged, i.e. the components (slider, toggle, etc.) are not interactive. But it works very well for the following ones. See the following video for an example.
Do you have any idea about this behavior ?
For completeness, the two code blocks I used come from Makie IntervalSlider and Makie Toggle tutorials. Here they are:
let
fig = Figure()
ax = Axis(fig[1, 1], limits = (0, 600, -2, 2))
hidexdecorations!(ax)
t = Observable(0.0)
points = lift(t) do t
x = range(t-1, t+1, length = 500)
@. sin(x) * sin(2x) * sin(4x) * sin(23x)
end
lines!(ax, points, color = (1:500) .^ 2, linewidth = 2, colormap = [(:blue, 0.0), :blue])
gl = GridLayout(fig[2, 1], tellwidth = false)
Label(gl[1, 1], "Live Update")
toggle = Toggle(gl[1, 2], active = false)
on(fig.scene.events.tick) do tick
toggle.active[] || return
t[] += tick.delta_time
end
fig
end
let
f = Figure()
Axis(f[1, 1], limits = (0, 1, 0, 1))
rs_h = IntervalSlider(f[2, 1], range = LinRange(0, 1, 1000),
startvalues = (0.2, 0.8))
rs_v = IntervalSlider(f[1, 2], range = LinRange(0, 1, 1000),
startvalues = (0.4, 0.9), horizontal = false)
labeltext1 = lift(rs_h.interval) do int
string(round.(int, digits = 2))
end
Label(f[3, 1], labeltext1, tellwidth = false)
labeltext2 = lift(rs_v.interval) do int
string(round.(int, digits = 2))
end
Label(f[1, 3], labeltext2,
tellheight = false, rotation = pi/2)
points = rand(Point2f, 300)
# color points differently if they are within the two intervals
colors = lift(rs_h.interval, rs_v.interval) do h_int, v_int
map(points) do p
(h_int[1] < p[1] < h_int[2]) && (v_int[1] < p[2] < v_int[2])
end
end
scatter!(points, color = colors, colormap = [:gray90, :dodgerblue], strokewidth = 0)
f
end