Update an external Observable in Makie recipe

In Julia, an observable can be passed as argument to a function, and when the function updates its value, the changes are visible from outside the function (the observable declared outside is updated).

Simple working example:

obs = Observable(0)
on(obs) do obs
  println("updated")
end
function updateobs(observable::Observable)
  observable[] += 1
end

updateobs(obs) # calls println("updated")

However, when the function is from a Makie recipe, the observable seems transformed, and cannot be updated anymore. I even tried to pass it as an attribute, without success. Is it possible to achieve that, or not with the current recipe architecture ? My solution for now is to not use a recipe, and define an independant plotting function, but it would be better to use a recipe.

Simple not working example:

obs = Observable([1,2,3])
on(obs) do obs
  println("updated")
end

@recipe(TestPlot) do scene
    Attributes(
        color = (:red, 0.8),
    )
end

function Makie.plot!(tp::TestPlot{<:Tuple})
    obs = tp[1]
    # update observable
    obs[] = obs.val .+ 1
    lines!(tp, obs, color = tp.color)
    tp
end

f = Figure()
ax = Axis(f[1,1])
testplot!(ax, obs)
# does not print "updated"

You are looking at a new observable inside the recipe that is created during the plotting pipeline. Try plot.args[1] maybe, but even that might be copied.

1 Like

Indeed, tp.args[1] instead of tp[1] is giving the original observable, thanks !