How to add dropdown menu inside Makie recipe?

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.

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 :wink:
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
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 :wink:

1 Like

So it slightly awkward but works pretty well:


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

3 Likes

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”.

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.

@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:

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> 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