Creating an animation with data from dataframe using GLMakie?

Hi,

Hoping to get some help figuring how to create an animation in Makie using data from a DataFrame. Specifically I was trying to animate a point moving through a line using the scatter function. Below is about as far as I got. Tried following a couple examples on this link (Animations) but didn’t really get the result I was looking for using data from a dataframe.
I can do this in Plots.jl by looping through eachindex of the dataframe, but can’t seem to figure out how to replicate it in Makie using the Observables framework. Observables are a new concept to me and it hasn’t quite clicked in my head yet.
I would appreciate any feedback.

Cheers,
RL

using DataFrames
using GLMakie

df = DataFrame(x= 1:100, y=1:100)

fig, ax = lines(data)
scatter(data, color=(:yellow, 0.5), strokecolor=:red, strokewidth=1)

I

Here is a simple example:

using DataFrames
using GLMakie

df = DataFrame(x = 1:100, y = 1:100)

# plot a line
lines(df.x, df.y)

# create an Observable object which stores a point's coordinate
p = Observable(Point2f(NaN, NaN))

# plot the point
scatter!(p, color=(:yellow, 0.5), strokecolor=:red, strokewidth=1)

# now update the Observable p will update the position of the point in the figure
for i in 1:100
    p[] = Point2f(df.x[i], df.y[i])
    sleep(0.1)
end

2 Likes

Thanks mate! This is helpful in understanding how to use observables to do this.

Cheers,

One last question, how would you get this example to work if an Axis is defined (see my code changes below)? I get the error at the bottom. I tried forcing the values of df.x and df.y to type Float32 and turning it to a Tuple, but that wasn’t successful. I also don’t really understand Makie.convert_arguments examples.

Best,
RL

df = DataFrame(x = 1:100, y = 1:100)

f = Figure(resolution = (900, 600))
ax = Axis(f[1, 1],
title = "Title",
xlabel = "x-axis",
ylabel = "y-axis",
titlecolor = "grey")

# plot a line
lines(ax, df.x, df.y)

# create an Observable object which stores a point's coordinate
p = Observable(Point2f(NaN, NaN))

# plot the point
scatter!(p, color=(:yellow, 0.5), strokecolor=:red, strokewidth=1)

# now update the Observable p will update the position of the point in the figure
for i in 1:100
    p[] = Point2f(df.x[i], df.y[i])
    sleep(0.1)
end

error for the code above

ERROR: `Makie.convert_arguments` for the plot type Lines{Tuple{Axis, Vector{Int64}, Vector{Int64}}} and its conversion trait PointBased() was unsuccessful.

The signature that could not be converted was:
::Axis, ::Vector{Float32}, ::Vector{Float32}

Makie needs to convert all plot input arguments to types that can be consumed by the backends (typically Arrays with Float32 elements).
You can define a method for `Makie.convert_arguments` (a type recipe) for these types or their supertypes to make this set of arguments convertible (See http://docs.makie.org/stable/documentation/recipes/index.html).

The error is caused by this line:

# plot a line
lines(ax, df.x, df.y)

When you want to plot on a specific axis, what you want to use is the mutating version of the plotting function (which always ends with an exclamation mark).

So simply change that line into:

lines!(ax, df.x, df.y)

will fix the error.

Extra note:
this line:
scatter!(p, color=(:yellow, 0.5), strokecolor=:red, strokewidth=1)
works here because it implicitly uses the latest axis. So if you have multiple axis in your figure, it’s better to pass the axis explicitly to avoid your plot appearing in the wrong place, i.e.
scatter!(ax, p, color=(:yellow, 0.5), strokecolor=:red, strokewidth=1)

1 Like

I understand… thank you so much!