# Errors using Makie plots with Observable metadata Vectors of variable length

**URL:** <https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469>\
**Category:** Visualization\
**Tags:** makie\
**Created:** [October 28, 2022, 9:12pm UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469 "2022-10-28T21:12:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![jpdoane](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jpdoane](https://discourse.julialang.org/u/jpdoane)\
**Post date:** [October 28, 2022, 9:12pm UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469/1 "2022-10-28T21:12:44Z")

</div>

I would like to generate a Makie animation that has a variable number of points and polygons per frame, and am running into some odd behavior. I am using scatter() and poly() with Observables holding the data points, and updating the Observables in a loop. The polygons should each have custom transparency, which is held in an Observable of Vector{RGBA}, and the scatter points should each have custom markersize, held in an Observable of Vector{Float}. Because the length of the data and metadata vectors must always be consistent, I am manually updating each Observable Vector, and then only notifying them together after the new data has been loaded.

I ran into a bug where the poly() update fails if the number of objects in the list changes:

```julia
ERROR: LoadError: Metadata array needs to have same length as data.
                    Found 6 data items, and 4 metadata items

```

I had been working on Makie v0.17.3, and discovered that this bug seems to be corrected in v0.18.1, for which the poly plot works as expected. However, the scatter plot which had worked fine in v0.17.3 is now failing with a similar error in v0.18.1.

Is this an odd confluence of related Makie bugs? Am I setting this plot up incorrectly? Or is varying the length of metadata vectors simply not supported? Any suggested workaround or alternate approaches to accomplishing this?

Reproducible example:

```julia
using GLMakie, Makie
using Colors

polys = Observable([rand(Point2f,3) for nn=1:2])
colors = Observable(rand(RGBA,2))
pts = Observable(rand(Point2f,2))
sz = Observable(rand(2))
update = Observable(true)

on(update) do _
    NN = rand(1:10) #only get an error if number of objects is changed...
    
    #update plot data, but dont notify Plots until all Observables are updated
    polys.val = [rand(Point2f,3) for nn=1:NN]
    colors.val = rand(RGBA,NN)
    pts.val = rand(Point2f,NN)
    sz.val = 10 .* rand(NN)
    
    notify(colors)
    notify(polys)
    notify(pts)
    notify(sz)
end

f = Figure();
ax = Axis(f[1,1])
xlims!(ax,0,1)
ylims!(ax,0,1)

# scatter(), variable number of points, custom markersize per point
# Works on v0.17.3, breaks on v0.18.1
Makie.scatter!(ax, pts, markersize=sz) 

# poly(), variable number of polys, custom RGBA per poly
# Works on v0.18.1, breaks on v0.17.3
Makie.poly!(ax, polys, color=colors)

display(f)

for mm=1:10
    notify(update)
    sleep(.1)
end

```

---

<div class="post-metadata">

**Author:** ![jpdoane](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jpdoane](https://discourse.julialang.org/u/jpdoane)\
**Post date:** [October 29, 2022, 4:31pm UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469/2 "2022-10-29T16:31:42Z")

</div>

I thought I decent workaround to this might be to delete the old plot object and generate a new one for each frame. I first tried this [per the documentation](https://docs.makie.org/v0.18.1/examples/blocks/axis/index.html#deleting_plots):

```julia
delete!(ax, sp)
sp = scatter!(ax, pts, markersize=sz) 

```

But this appears to corrupt the axis itself, e.g. all axis tick labels become grey boxes:

 ![Capture](https://global.discourse-cdn.com/julialang/original/3X/4/e/4e52d46c3bacf87087365d326d2e6d0b01c00662.png)

(Edit: this rendering issue seems to be specific to GLMakie, and does not occur with CairoMakie)

I also tried manually deleting the plot from the scene, e.g.

```julia
deleteat!(ax.scene.plots, findfirst(ax.scene.plots .== sp))

```

But this does not actually remove the old plot until an explicit redraw (e.g. `display(figure)`) which is rather slow.

---

<div class="post-metadata">

**Author:** ![adanalis](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@adanalis](https://discourse.julialang.org/u/adanalis)\
**Post date:** [December 5, 2023, 2:15am UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469/3 "2023-12-05T02:15:50Z")

</div>

I’m facing a similar problem when using scatter() (on GLMakie 0.9.2) with markersize set to a Vector. Namely, if I add a new element to be plotted and a size for it and then I notify() both Observables, then I get the following error:

DimensionMismatch: arrays could not be broadcast to a common size; got a dimension with lengths 8 and 9

However, if I print the two Observables they both have 9 elements.

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [December 5, 2023, 2:24am UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469/4 "2023-12-05T02:24:03Z")

</div>

This is addressed in the documentation [here](https://docs.makie.org/stable/explanations/nodes/#problems_with_synchronous_updates).

---

<div class="post-metadata">

**Author:** ![adanalis](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@adanalis](https://discourse.julialang.org/u/adanalis)\
**Post date:** [December 5, 2023, 4:17pm UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469/5 "2023-12-05T16:17:24Z")

</div>

Can you please clarify. The documentation says to mutate the content of one observable withoug truggering it’s listeners, but  
that’s what my code does anyway. Please see the reproducer below and let me know if I’m misusing something.

```julia
using GLMakie

function my_plot()

    pnts = [Point2f(x,x*x) for x in 1:8]
    sz = [10.0+x for x in 1:8]

    positions = Observable(pnts)
    sizes = Observable(sz) 

    fig, ax, p = scatter(positions, markersize=sizes)

    on(events(ax.scene).mousebutton, priority = 2) do event
        if event.button == Mouse.left && event.action == Mouse.press
            if Keyboard.a in events(fig).keyboardstate
                # Add marker
                push!(positions[], mouseposition(ax))
                push!(sizes[], 12.345)
                show(positions)
                println()
                show(sizes)
                println()
# When notify(sizes) is commented out the plot does not update.
# When not in comment, the program crashes with "DimensionMismatch", even if notify(positions) is commented out.
# notify(sizes)
                notify(positions)
                return Consume(true)
            end
        end
        return Consume(false)
    end         
                
    fig         
end    

    wait(display(my_plot()))

```

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [December 5, 2023, 4:41pm UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469/6 "2023-12-05T16:41:56Z")

</div>

> [@adanalis](#):
>
> ```julia
> push!(positions[], mouseposition(ax))
> push!(sizes[], 12.345)
> 
> ```

These two lines are already notifying since the use `getindex`. Try

```julia
push!(positions.val, mouseposition(ax))
push!(sizes.val, 12.345)

```

---

<div class="post-metadata">

**Author:** ![adanalis](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@adanalis](https://discourse.julialang.org/u/adanalis)\
**Post date:** [December 5, 2023, 4:50pm UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469/7 "2023-12-05T16:50:05Z")

</div>

This does not fix it in my environment. The problem seems to be with “sizes”. The following code still crashes with DimensionMismatch:

```julia
using GLMakie

function my_plot()

    pnts = [Point2f(x,x*x) for x in 1:8]
    sz = [10.0+x for x in 1:8]

    positions = Observable(pnts)
    sizes = Observable(sz)

    fig, ax, p = scatter(positions, markersize=sizes)

    on(events(ax.scene).mousebutton, priority = 2) do event
        if event.button == Mouse.left && event.action == Mouse.press
            if Keyboard.a in events(fig).keyboardstate
                push!(positions.val, mouseposition(ax))
                push!(sizes.val, 12.345)
                notify(sizes)
                return Consume(true)
            end
        end
        return Consume(false)
    end

    fig
end

    wait(display(my_plot()))

```

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [December 5, 2023, 5:03pm UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469/8 "2023-12-05T17:03:37Z")

</div>

Oh, this is actually a problem in the bezierpath code path… This works:  
`scatter(positions, markersize=sizes, marker=Circle)`

```julia
using GLMakie

function my_plot()

    pnts = [Point2f(x, x * x) for x in 1:8]
    sz = [10.0 + x for x in 1:8]

    positions = Observable(pnts)
    sizes = Observable(sz)

    fig, ax, p = scatter(positions, markersize=sizes, marker=Circle)

    on(events(ax.scene).mousebutton, priority=2) do event
        if event.button == Mouse.left && event.action == Mouse.press
            if Keyboard.a in events(fig).keyboardstate
                mp = mouseposition(ax)
                @show mp
                push!(positions[], mp)
                push!(sizes[], 12.345)
                notify(positions)
                notify(sizes)
                return Consume(true)
            end
        end
        return Consume(false)
    end

    fig
end

wait(display(my_plot()))

```

Background, Circle is a primitive we render directly on the GPU, while bezierpaths circles are a bit more complicated. The default is a bezier circle.

---

<div class="post-metadata">

**Author:** ![adanalis](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@adanalis](https://discourse.julialang.org/u/adanalis)\
**Post date:** [December 5, 2023, 6:16pm UTC](https://discourse.julialang.org/t/errors-using-makie-plots-with-observable-metadata-vectors-of-variable-length/89469/9 "2023-12-05T18:16:48Z")

</div>

Thank you @sdanisch. I can confirm that adding “marker=Circle” to scatter() fixes the problem in my environment.
