# How to add dropdown menu inside Makie recipe?

**URL:** https://discourse.julialang.org/t/how-to-add-dropdown-menu-inside-makie-recipe/62005
**Category:** Visualization
**Tags:** makie, recipe, interactivity
**Created:** [May 28, 2021, 4:28pm UTC](https://discourse.julialang.org/t/how-to-add-dropdown-menu-inside-makie-recipe/62005 "2021-05-28T16:28:55Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [May 28, 2021, 4:28pm UTC](https://discourse.julialang.org/t/how-to-add-dropdown-menu-inside-makie-recipe/62005/1 "2021-05-28T16:28:55Z")

</div>

Is there an example somewhere of a full recipe with interactive elements? I am searching through the master branch documentation but can’t find an example.

---

<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: [May 28, 2021, 4:53pm UTC](https://discourse.julialang.org/t/how-to-add-dropdown-menu-inside-makie-recipe/62005/2 "2021-05-28T16:53:23Z")

</div>

So the recipes right now are conceptionally more like adding new graphical drawing methods, which compose very well with all the other recipes. They do allow you to define interactions based on some events, but the current buttons/menus etc need to have a place in the figures layout.  
This doesn’t work very well with composability of recipes - since how do you compose recipes that mutate the layout and add new elements like that?  
I’ve been thinking to add a new type of overload / recipe that lets you “own” a subfigure area in the gridlayout, so that you can add new sub grids in that slot, and also create the kind of axis/titles/decorations you want have 😉  
I think it already works to overload `plot(P::PlotFunc, fp::FigurePosition, args...; axis = NamedTuple(), kwargs...)` [Makie.jl/figureplotting.jl at master · JuliaPlots/Makie.jl · GitHub](https://github.com/JuliaPlots/Makie.jl/blob/master/src/figureplotting.jl#L50) …  
PlotFunc is the type (Mesh/Scater/…) which can then be passed to `plot!(ax, P, args...)`

Once we figured out the API for that we can clean it up and document it 😉

---

<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: [May 28, 2021, 5:12pm UTC](https://discourse.julialang.org/t/how-to-add-dropdown-menu-inside-makie-recipe/62005/3 "2021-05-28T17:12:54Z")

</div>

So it slightly awkward but works pretty well:

```julia

struct Solution
    data::Any
end

function Makie.plot(P::Type{<: AbstractPlot}, fig::Makie.FigurePosition, arg::Solution; axis = NamedTuple(), kwargs...)

    menu = Menu(fig, options = ["viridis", "heat", "blues"])

    funcs = [sqrt, x->x^2, sin, cos]

    menu2 = Menu(fig, options = zip(["Square Root", "Square", "Sine", "Cosine"], funcs))

    fig[1, 1] = vgrid!(
        Label(fig, "Colormap", width = nothing),
        menu,
        Label(fig, "Function", width = nothing),
        menu2;
        tellheight = false, width = 200)

    ax = Axis(fig[1, 2]; axis...)

    func = Node{Any}(funcs[1])

    ys = @lift($func.(arg.data))

    scat = plot!(ax, P, Attributes(color = ys), ys)

    cb = Colorbar(fig[1, 3], scat)

    on(menu.selection) do s
        scat.colormap = s
    end

    on(menu2.selection) do s
        func[] = s
        autolimits!(ax)
    end

    menu2.is_open = true

    return Makie.AxisPlot(ax, scat)
end

f = Figure();
lines(f[1, 1], Solution(0:0.3:10))
scatter(f[1, 2], Solution(0:0.3:10))
f |> display

```

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

---

<div class="post-metadata">

### Author: ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)
#### Post date: [May 28, 2021, 6:06pm UTC](https://discourse.julialang.org/t/how-to-add-dropdown-menu-inside-makie-recipe/62005/4 "2021-05-28T18:06:24Z")

</div>

> [@sdanisch](#):
>
> I’ve been thinking to add a new type of overload / recipe that lets you “own” a subfigure area in the gridlayout, so that you can add new sub grids in that slot, and also create the kind of axis/titles/decorations you want have 😉

I’ve also being thinking along those lines. I think we’d need it anyway for things like `corrplot` or `marginalhist`. Basically “plot on a figure position rather than on an 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: [May 28, 2021, 6:08pm UTC](https://discourse.julialang.org/t/how-to-add-dropdown-menu-inside-makie-recipe/62005/5 "2021-05-28T18:08:17Z")

</div>

yes, and I guess a lot of other simple one-axis recipes could just be handled by processing a default `axis` keyword that carries axis labels, scales, ticks etc. Currently, this wouldn’t be picked up from a plot object’s theme. I guess the logic would be, if an axis is created through a recipe, check if that recipe has associated axis settings. These would be optional though, in the sense that they wouldn’t be applied when mutating an existing axis.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [May 28, 2021, 8:23pm UTC](https://discourse.julialang.org/t/how-to-add-dropdown-menu-inside-makie-recipe/62005/6 "2021-05-28T20:23:17Z")

</div>

@sdanisch I tried to replicate the example in MeshViz.jl but without success. Suppose my argument is `arg::MeshData` and my recipe is `Viz{<:Tuple{MeshData}}`, which already has a `Makie.plot!` method. This is the minimal example I tried:

```julia
function Makie.plot(P::Type{Viz{<:Tuple{MeshData}}}, fig::Makie.FigurePosition,
                    arg::MeshData; axis = NamedTuple(), kwargs...)

  menu = Makie.Menu(fig, options = ["viridis","heat","blues"])

  fig[1, 1] = Makie.vgrid!(menu, tellheight=false, width=200)

  ax = Makie.Axis(fig[1, 2]; axis...)

  plt = Makie.plot!(ax, P, Attributes(), rand(100))

  Makie.AxisPlot(ax, plt)
end

```

When I try to plot a MeshData object, the menu isn’t shown:

```julia
julia> using Meshes, MeshViz
julia> import GLMakie

julia> data = meshdata(
  Point3[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],
  connect.([(1,2,3),(3,4,1)]),
  etable = (z=[1,2], w=[3,4])
)
julia> data = meshdata(
         Point3[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],
         connect.([(1,2,3),(3,4,1)]),
         etable = (z=[1,2], w=[3,4])
       )
2 MeshData{3,Float64}
  variables (rank 2)
    └─w (Int64)
    └─z (Int64)
  domain: 2 SimpleMesh{3,Float64}

viz(data)

```

The master branch of MeshViz.jl has the current version I am working with: [https://github.com/JuliaGeometry/MeshViz.jl](https://github.com/JuliaGeometry/MeshViz.jl)
