Animated rotation of 3D plot in GLMakie

172 views Asked by At

Using GLMakie, I want to incrementally rotate a 3D plot, saving an animation of the result.

Each frame should rotate the plot by a small angle (say, 1 degree). Over the course of the animation, the plot should rotate 360 degrees.

Here is a video example of what I mean (ish): https://imgur.com/a/ggTCVVm

Here's what I currently have:

using GLMakie

xs = -10:0.5:10
ys = -10:0.5:10
zs = [cos(x) * sin(y) for x in xs, y in ys]

# Explicitly create figure and axes - is this necessary?
fig = GLMakie.Figure()
ax = GLMakie.Axis3(fig[1, 1])
Makie.surface!(xs, ys, zs)
camera = Makie.cam3d!(fig.scene) # Ensure we have a 3D camera - is this necessary?

N_camera_steps = 100

GLMakie.record(
    fig,
    "test.mp4",
    [2π/N_camera_steps for _ = 1:N_camera_steps];
    framerate = 30,
) do angle 
    GLMakie.rotate_cam!(fig.scene, camera, (angle, 0, 0)) # Only rotate about one axis
end

However, this produces an .mp4 that shows a static plot only.

I might be misunderstanding how complex this is - I haven't really considered frames of reference, or whether I should be trying to rotate the camera or the plot.

How can I achieve my desired result in GLMakie?

1

There are 1 answers

0
theo-brown On BEST ANSWER

After asking around on the GLMakie Slack, I came up with the following solution:

using GLMakie

xs = -10:0.5:10
ys = -10:0.5:10
zs = [cos(x) * sin(y) for x in xs, y in ys]

fig = GLMakie.Figure()
ax = GLMakie.Axis3(fig[1, 1])
Makie.surface!(xs, ys, zs)

start_angle = π / 4
n_frames = 120
ax.viewmode = :fit # Prevent axis from resizing during animation
record(fig, "test.mp4", 1:n_frames) do frame
    ax.azimuth[] = start_angle + 2pi * frame / n_frames
end

I found that explicitly creating the axes and figure was necessary, as I couldn't figure out how to get the axis and figure object from the call to surface.

The key thing was to modify the ax.aximuth variable.