3D surfaces + time slider

Hi,

PlotlyJS provides the following code to represent multiple surfaces at once (see multiple surfaces):

julia> using PlotlyJS

julia> function multiple_surface()
           z1 = Vector[[8.83, 8.89, 8.81, 8.87, 8.9, 8.87],
                       [8.89, 8.94, 8.85, 8.94, 8.96, 8.92],
                       [8.84, 8.9, 8.82, 8.92, 8.93, 8.91],
                       [8.79, 8.85, 8.79, 8.9, 8.94, 8.92],
                       [8.79, 8.88, 8.81, 8.9, 8.95, 8.92],
                       [8.8, 8.82, 8.78, 8.91, 8.94, 8.92],
                       [8.75, 8.78, 8.77, 8.91, 8.95, 8.92],
                       [8.8, 8.8, 8.77, 8.91, 8.95, 8.94],
                       [8.74, 8.81, 8.76, 8.93, 8.98, 8.99],
                       [8.89, 8.99, 8.92, 9.1, 9.13, 9.11],
                       [8.97, 8.97, 8.91, 9.09, 9.11, 9.11],
                       [9.04, 9.08, 9.05, 9.25, 9.28, 9.27],
                       [9, 9.01, 9, 9.2, 9.23, 9.2],
                       [8.99, 8.99, 8.98, 9.18, 9.2, 9.19],
                       [8.93, 8.97, 8.97, 9.18, 9.2, 9.18]]
           z2 = map(x->x.+1, z1)
           z3 = map(x->x.-1, z1)
           trace1 = surface(z=z1, colorscale="Viridis")
           trace2 = surface(z=z2, showscale=false, opacity=0.9, colorscale="Viridis")
           trace3 = surface(z=z3, showscale=false, opacity=0.9, colorscale="Viridis")
           plot([trace1, trace2, trace3])
       end
multiple_surface (generic function with 1 method)

julia> multiple_surface()
[ Info: Listening on: 127.0.0.1:7752, thread id: 2

And it works as expected:

My current need is a touch more complex: I am trying to visualize several such surfaces as they evolve through time, and a slider type input would be ideal to move through history and stop at certain timestamps.

Has anybody created such a thing before? Note that I’m open minded, doesn’t have to be done in PlotlyJS.

That’s my cue:

using GLMakie


f = Figure()
ax = Axis3(f[1, 1])

time = Observable(0.0)

for (i, omega) in enumerate([1, 2, 4])
    surfdata = @lift([cos($time + x * omega) * sin($time + y * omega)
        for x in 0:0.1:2pi, y in 0:0.1:2pi])
    surf = surface!(ax, surfdata)
    translate!(surf, 0, 0, 10 * (i-1))
end

# currently, Makie does not detect the limits of `translate!`d plot objects correctly
zlims!(ax, -5, 25)

slg = SliderGrid(f[2, 1], (; range = 0:0.01:10, label = "Time"))

on(slg.sliders[1].value) do v
    time[] = v
end

f

2 Likes

Pretty cool. Let me try to find the relevant documentation and apply it to my use case. Thank you.