Makie - passing keyword arguments through a @recipe

Hi,

I’m trying to define a new recipe in Makie that is essentially an enhanced contour plot, and I would like any kwargs that get passed in the call for my new recipe to automatically get passed-through to my call to contour!. But it’s not clear to me how to do this.

More information: I’m trying to make new plot recipe that will use a kernel density estimate to plot 2D contours of the density of some points. I want kdecontour(x, y; kwargs...) to become a contour plot that plots density contours, and passes the options in kwargs onward to contour. My recipe looks like

@recipe(KDEContour, x, y) do scene
    Theme(
        levels = [0.1, 0.5],
        xexpansionfactor = 0.1,
        yexpansionfactor = 0.1,
        xgridsize=128,
        ygridsize=129
    )
end
function Makie.plot!(kdecontour::KDEContour)
    x = kdecontour.x[]
    y = kdecontour.y[]

    pts = vcat(x', y')
    k = KDE(pts)

    p_kde_pts = [pdf(k, pts[:,i]) for i in axes(pts, 2)]
    p_levels = [quantile(p_kde_pts, l) for l in kdecontour.levels[]]

    dx = maximum(x)-minimum(x)
    dy = maximum(y)-minimum(y)

    fx = kdecontour.xexpansionfactor[]/2
    xgrid = range(minimum(x)-fx*dx, maximum(x)+fx*dx, length=kdecontour.xgridsize[])

    fy = kdecontour.yexpansionfactor[]/2
    ygrid = range(minimum(y)-fy*dy, maximum(y)+fy*dy, length=kdecontour.ygridsize[])

    z = [pdf(k, [x, y]) for x in xgrid, y in ygrid]

    # I want any additional kwargs to get passed along to this invocation of `contour!`
    contour!(kdecontour, xgrid, ygrid, z; levels=p_levels)
end

(Nevermind that I’m ignoring all the Observable machinery for now—I’ll put that in later.). How do I do this?

Will

There’s kdecontour.attributes, you could copy that and pop! the observables you need elsewhere from it and then pass the remaining thing to contour

Sweet! That’s what I didn’t know about—thanks!

In newer versions you can also do:

contour!(kdecontour, shared_attributes(kdecontour, Contour), xgrid, ygrid, z; levels=p_levels)
1 Like