CairoMakie AssertionError: length(positions) == length(colors) when trying to record

Hi, I’ve been trying to make this code run but I don’t know how to fix a problem. I think the problem happens too deep in the stack call that I just cannot find where in particular is it occurring:

My goal is to have an animation. Each frame is formed by several contour plots stacked on top of one another in a 3d axis like this:

GLMakie crashes with a different error.

The animation has now 108 frames but I will increase this number.


using CairoMakie, NCDatasets
RH_high,x,y,z_levels,t = Dataset(joinpath(ENV["HOME"],"")) do ds
    RH_high = variable(ds,"RH")[:,:,:,:] :: Array{UInt8,4}
    x = variable(ds,"x")[:] :: Array{Float32,1}
    y = variable(ds,"y")[:] :: Array{Float32,1}
    z_levels = variable(ds,"z")[:] :: Array{Float32,1}
    t = variable(ds,"times")[:] :: Array{Float32,1}
### Let us create several observables. Each observable corresponds to a different contour plot.
time_idx = Node(1)
rhs =  BitMatrix[]
for i in 1:length(z_levels)
rh_observables = [Node(i) for i in rhs];

fig = Figure()
ax = Axis3(fig[1,1])
ax.limits[] = ((0,1024),(0,1024),(0,z_levels[end]))
for i in 1:length(z_levels)
    contour!(ax,x,y,rh_observables[i], transformation = (:xy, z_levels[i]))

### Until here, the result is the image posted above.

### The problem: In the following section, I am trying to record my animation. This fails when i==45
record(fig, joinpath(".","3d_rh_contours.mp4"), 1:length(t); framerate = 10, compression = 0) do curr_t
    @info curr_t
    for i in 1:length(z_levels)
        rhs[i][:] .= RH_high[:,:,i,curr_t][:]
    [i[] = i[] for i in rh_observables]
    time_idx[] = curr_t

The recording step breaks with the error:

AssertionError: length(positions) == length(colors)

[1] draw_multi(primitive::Lines{Tuple{Vector{Point{2, Float32}}}}, ctx::Cairo.CairoContext, positions::Vector{Vec{2, Float32}}, colors::Vector{ColorTypes.RGBA{Float32}}, linewidths::Vector{Float32}, dash::Nothing)

This breaks in step 45, but the particular number is not very important: if I start from 42 instead of 1, now it breaks around 90
What I am doing inside the record block is: first, I modify in-place the contents of rhs. Then I trigger an update of the observables. I am doing this because I hoped the problem was being caused by two things updating out of sync, but that didn’t solve the problem.

I would immensely appreciate any help.

I saved the data to reproduce into a 4MB netcdf file that can be found here:

Julia Version 1.6.0
Commit f9720dc2eb (2021-03-24 12:55 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Xeon(R) CPU E5-2698 v3 @ 2.30GHz
LIBM: libopenlibm
LLVM: libLLVM-11.0.1 (ORCJIT, haswell)

]st CairoMakie:
[13f3f980] CairoMakie v0.4.2

GLMakie dies with a very different error.

The error comes when drawing the lines inside the contour object it seems. You could inspect c.plots[1].color[] and c.plots[1][1] where c is your contour plot to see what the colors and positions are like at that time point. Could in principle be a bug in contour, but it’s weird that you get the error in 45 if you start at 1, but in 90 if you start at 42 (which includes 45 right)?

Maybe you can log the number of colors and points for each frame to see what’s going on there?

Hi Julius. Thanks for taking the time to look into this.

I changed my code to initially plot the step 45 ( time_idx = Node(45) instead of Node(1) ) and the plot appears without problems. The lengths of both c.plots[1].color[] and c.plots[1][1][] is the same: 13669 . This furthers the hypothesis that there is nothing especially wrong about the data at that point. If I add @show length(colors), length(positions) in the source code before the “assert” I found that, when it fails, positions has exactly twice as much elements as colors, the length of positions being the correct one.

The AssertionError: length(positions) == length(colors) and the not important data point reminds me of the time I tried doing an animation of scatter(Observable(vectorx),Observable(vectory)) and a similar error appeared because the observables were momentarily out of sync at some random timesteps. That was solved by doing something like scatter(Observable(Point2f0[])) or something like that.

In this case, however, I don’t manage myself two observables that may get out of sync (or at least I don’t see where).

Could it be the case that something like that is happenning in the insides of Makie?