# Interactive Menu with AlgebraOfGraphics / GLMakie

**URL:** <https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842>\
**Category:** Visualization\
**Tags:** interactivity, algebraofgraphics\
**Created:** [January 31, 2023, 10:47pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842 "2023-01-31T22:47:32Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)\
**Post date:** [January 31, 2023, 10:47pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/1 "2023-01-31T22:47:32Z")

</div>

Hello,  
I am trying to have an interactive AlgebraofGraphics plot, e.g. with a menu to select which variable is plotted.  
A MWE is

```julia
x1=rand(50)
y1=10x1.^2
y2=x1 .+ randn(50)
df = DataFrame((;x1, y1, y2))

var=Observable("y1")

fig = @lift((data(df) * 
    mapping(:x1, Symbol($var), color=:x1) * 
    (visual(Scatter) + smooth(;span=0.3, degree=1)) |> draw).figure)

menu = Menu(fig[], options = ["y1","y2"] , default = "y1")
fig[][1, 3] = vgrid!(
        Label(fig[], "Variable", width = nothing),
        menu,
        tellheight = false, width = 200)
    
 on(menu.selection) do s
         var[] = s
end

@lift(display($fig))

```

It is kind of clear that it cannot work, because with `fig[]` I destroy the observable, but the example shows what I want (it does display the initial figure and also updates, but the menu gets lost).

 ![image](https://global.discourse-cdn.com/julialang/original/3X/4/0/401040cbc9e30985cde460ea65e3a0702a8be75c.png)

Is there is a GLMakie expert to help…?

---

<div class="post-metadata">

**Author:** ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)\
**Post date:** [February 1, 2023, 9:24am UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/2 "2023-02-01T09:24:32Z")

</div>

This comes closer, but now I don’t know how to delete the previous plot (and if I am roughly doing the right thing):

```julia
var=Observable("y1")
fig=Figure()
axentry = draw!(fig[1,1:1], data(df) * 
    mapping(:x1, Symbol(var[]), color=:x1) * 
    (visual(Scatter) + smooth(;span=0.3, degree=1)))
Colorbar(fig[:, 2])

menu = Menu(fig, options = ["y1","y2"] , default = "y1")
fig[2,1] = hgrid!(
        Label(fig, "Variable", width = nothing),
        menu,
        tellheight = true)
    
 on(menu.selection) do s
         var[] = s
         draw!(fig[1,1], data(df) * 
    mapping(:x1, Symbol(s), color=:x1) * 
    (visual(Scatter) + smooth(;span=0.3, degree=1)))
end

```

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [February 2, 2023, 1:27am UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/3 "2023-02-02T01:27:10Z")

</div>

You don’t have to `@lift` the figure or redraw it (not sure if this is an AlgebraOfGraphics thing. I only use GLMakie for interactivity so far). I would make the x data `Observable` and then `@lift` the y data (Note you need to use a `$` in front of the x variable). The magic of Makie and `Observable`s is that you can just use regular GLMakie functions and put `Observable`s as x and y and Makie will automatically draw the new plot when any `Observable` changes (you can even change attributes like the `xlabel` and `ylabel`. Here’s how I would do it:

```julia
using GLMakie

x1 = Observable(rand(50))
y_current = @lift(10 .* $x1.^2)

y1 = @lift(10 .* $x1.^2)
y2 = @lift($x1 .+ randn(50))

ys = [y1, y2]

fig = Figure()
display(fig)
ax = Axis(fig[1, 1], xlabel = "x1", ylabel = "y1")
scatter!(ax, x1, y_current)

menu = Menu(fig, options = ["y1","y2"] , default = "y1")
fig[1, 2] = vgrid!(
        Label(fig, "Variable", width = nothing),
        menu,
        tellheight = false, width = 200)
    
 on(menu.selection) do _
    i = to_value(menu.i_selected)
    y_current[] = to_value(ys[i])
end

```

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [February 2, 2023, 1:28am UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/4 "2023-02-02T01:28:37Z")

</div>

I’m working on a small set of interactive examples. I don’t have any menu examples right now, but maybe this will give you some ideas:

> **[GitHub - garrekstemo/InteractivePlotExamples.jl: Interactive plot examples...](https://github.com/garrekstemo/InteractivePlotExamples.jl)**
>
> Interactive plot examples using GLMakie, the GPU-powered Julia plotting package - GitHub - garrekstemo/InteractivePlotExamples.jl: Interactive plot examples using GLMakie, the GPU-powered Julia plo...

---

<div class="post-metadata">

**Author:** ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)\
**Post date:** [February 2, 2023, 5:11am UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/5 "2023-02-02T05:11:19Z")

</div>

Thanks @garrek,  
yes I know I can do it like that directly in GLMakie, but I wanted to take advantage of `AlgebraOfGraphics`, where it seems one cannot make “inner parameters” an Observable, cf. [Update xlims in interactive GLMakie - #3 by mreichMPI-BGC](https://discourse.julialang.org/t/update-xlims-in-interactive-glmakie/93825/3)

So, I am still wondering how it can be done in AoG…

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 2, 2023, 6:53am UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/6 "2023-02-02T06:53:26Z")

</div>

I don’t think AlgebraOfGraphics sets up observables such that you can change the inputs and expect the whole Figure to change. For example, this would also entail Axes appearing and disappearing if you have facetting, which is not that easy to implement compared to changing a plot’s color or data.

---

<div class="post-metadata">

**Author:** ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)\
**Post date:** [February 2, 2023, 1:26pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/7 "2023-02-02T13:26:50Z")

</div>

Ok, yet with my post [Interactive Menu with AlgebraOfGraphics / GLMakie - #2 by mreichMPI-BGC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/2) I was close. If I knew how to delete the previous plot just before the `draw!` statement in the `on` block, it would be ok. I believe it should be possible, but some intuitive things did not work.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 2, 2023, 2:23pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/8 "2023-02-02T14:23:36Z")

</div>

You could try this on the Axis:

> [@Removing row from GridLayout](https://discourse.julialang.org/t/removing-row-from-gridlayout/93196/6):
>
> This should work for clearing plots: for c in contents(menugrid[end, :]) # clean up plots and some observables empty!(c.blockscene) delete!(c) end trim!(menugrid) I’m not sure how complete the observable cleanup is with this. I wouldn’t be surprised if this leaves behind some ghost interactions, like an invisible button you can still press. If that is the case it would be good to open an issue for this.

So, `empty!(ax.blockscene)` and `delete!(ax)`

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [February 2, 2023, 3:59pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/9 "2023-02-02T15:59:17Z")

</div>

This one works, if you are only using 1 Axis

```julia
using AlgebraOfGraphics, GLMakie
using DataFrames

x1=rand(50)
y1=10x1.^2
y2=x1 .+ randn(50)
df = DataFrame((;x1, y1, y2))

var=Observable("y1")
fig=Figure()

axentry = draw!(fig[1,1:1], data(df) * 
    mapping(:x1, Symbol(var[]), color=:x1) * 
    (visual(Scatter) + smooth(;span=0.3, degree=1)))
Colorbar(fig[:, 2])

menu = Menu(fig, options = ["y1","y2"] , default = "y1")
fig[2,1] = hgrid!(
        Label(fig, "Variable", width = nothing),
        menu,
        tellheight = true)
    
 on(menu.selection) do s
         var[] = s
         Makie.delete!(fig.current_axis[])
         draw!(fig[1,1], data(df) * 
    mapping(:x1, Symbol(s), color=:x1) * 
    (visual(Scatter) + smooth(;span=0.3, degree=1)))
end
fig

```

For more complicated layouts we will need a list of all Axis plotted. @jules how do we get the axis being plotted at `fig[1,1])` ?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 2, 2023, 4:27pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/10 "2023-02-02T16:27:02Z")

</div>

[https://docs.makie.org/stable/documentation/figure/#retrieving\_objects\_from\_a\_figure](https://docs.makie.org/stable/documentation/figure/#retrieving_objects_from_a_figure)

---

<div class="post-metadata">

**Author:** ![mreichMPI-BGC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mreichmpi-bgc/32/43775_2.png) [@mreichMPI-BGC](https://discourse.julialang.org/u/mreichMPI-BGC)\
**Post date:** [February 2, 2023, 4:42pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/11 "2023-02-02T16:42:18Z")

</div>

I think I even tried that, but I don’t get it deleted ☹

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/1/719c5dd100282db74ac617009b540e2581808c02.png)

Restarted, updated: It works now. Thanks!

Before, the plot was nominally deleted (`nothing`), but still dangled in the window (but did not resize)

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [February 2, 2023, 5:04pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/12 "2023-02-02T17:04:17Z")

</div>

yes, this works with a simpler workflow. But, what if is more nested, i.e., a GridLayout? which is the case here:

```julia
contents(fig[1,1])
1-element Vector{Any}:
 GridLayout[1, 1] (1 children)

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 2, 2023, 5:17pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/13 "2023-02-02T17:17:29Z")

</div>

Then you continue into the GridLayout and delete everything there as well.

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [February 2, 2023, 5:31pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/14 "2023-02-02T17:31:10Z")

</div>

😄 I tried, but without being able to find the actual axis 😆

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 2, 2023, 5:40pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/15 "2023-02-02T17:40:24Z")

</div>

AlgebraOfGraphics nests these things, but not so far that you shouldn’t be able to find them 😉

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [February 2, 2023, 5:53pm UTC](https://discourse.julialang.org/t/interactive-menu-with-algebraofgraphics-glmakie/93842/16 "2023-02-02T17:53:46Z")

</div>

Ah I see. Sorry I misunderstood.
