Animating a 3D scatter plot in GLMakie

Hi all,

I am trying to create an animation of a 3D scatter plot in GLMakie. In principle, I thought that it would be straightforward to adapt the 2D animation from the documentation, but this has proven to be more difficult than initially thought. There are two problems. First, the scatter plot is 2D instead of 3D. Second, it does not animate.

using GLMakie
points = Observable(Point3f[(0, 0, 0)])
fig, ax = scatter(points)

frames = 1:30

record(fig, "append_animation.mp4", frames;
        framerate = 30) do frame
    new_point = Point3f(frame, frame, frame)
    points[] = push!(points[], new_point)
end

The Axis is in 2D because the first point has a z coordinate of zero, so the heuristic that chooses 3d or 2d kind of fails. You can manually make an LScene or Axis3, though.

Thank you for your response. Unfortunately, I encounter the same problem with non-zero values:

using GLMakie

points = Observable(Point3f[(1, 1, 1)])

fig, ax = scatter(points)

Maybe I’m misremembering then, and it’s the extent in z that’s zero which causes this. We’ll probably change that to an input type heuristic in the future.

Is there a solution using Axis3? Its not clear to me how to properly construct it. I tried the following:

using GLMakie
points = Observable(Point3f[(1, 1, 1)])
fig, _ = scatter(points)
ax = Axis3(fig)
frames = 1:30

record(fig, "append_animation.mp4", frames;
        framerate = 30) do frame
    new_point = Point3f(frame, frame, frame)
    points[] = push!(points[], new_point)
end

It places a 3D plot inside a 2D plot (lower left corner).

fig = Figure()
ax = Axis3(fig[1, 1])
scat = scatter!(ax, ...)
...

Or

fig, ax3, scat = scatter(..., axis = (; type = Axis3))

Awsome. Thank you. That correctly creates a 3D scatter plot. However, the points still do not display:

points = Observable(Point3f[(.5, .5, .5)])

fig, ax, scat = scatter(points, axis = (;type=Axis3))

Did I do something incorrectly or is there a bug?

Oh well, there’s a long-standing bug with scatter markers in Axis3, for some reason they come out really really small. As a hacky workaround, you can set the markersize to something like 1000 to see them, the projection matrix of the axis is not compensated for correctly it seems, but I’m not too familiar with the sprite shader.

1 Like

Jules, thank you for your help. I added a working example below for anyone who might be interested.

using GLMakie
points = Observable(Point3f[(1, 1, 1)])
fig, ax, scat = scatter(points, axis = (;type=Axis3), markersize = 4000)
limits!(ax, 0, 30, 0, 30, 0, 30)

frames = 1:30

record(fig, "append_animation.mp4", frames;
        framerate = 30) do frame
    new_point = Point3f(frame, frame, frame)
    points[] = push!(points[], new_point)
end