Axis-relative positioning

I want to say Axis(ax[1,1]; bbox = BBox(x,x+100,y,y+50)) with the x and y being on the scale of ax’s axes – i.e. in data space. But ax[1,1] doesn’t work so I use Axis(fig, and so x and y are relative to fig’s coordinates, not ax’s. Can it be done?

using GLMakie
let fig = Figure()
    ax = Axis(fig[1,1])
    m = 40
    n = 20
    xs = 2000rand(m)
    ys = 1000rand(m)
    axs = map(xs, ys) do x,y
        a = Axis(fig, bbox = BBox(x,x+100,y,y+50))
        scatter!(a, rand(n), rand(n))
    end
    fig
end

You can compute the positions using ax.scene.viewport and ax.finallimits observables

1 Like

I guess like this.

let fig = Figure()
    xmax = 4(2π)
    sxs = (0:.1:xmax)
    f(x) = x^2
    ax = Axis(fig[1,1])
    scatter!(ax, sxs, f)
    n = 5
    xs = sxs[ceil.(Int, range(firstindex(sxs), lastindex(sxs); length=5))] .+ 3
    ys = f.(xs) .+ 85
    axs = map(xs, ys) do x,y
        bbox = lift(ax.scene.viewport, ax.finallimits) do vp, axlims
            ((vp_xo, vp_yo), (vp_xw, vp_yw)) = vp.origin, vp.widths
            ((ax_xo, ax_yo), (ax_xw, ax_yw)) = axlims.origin, axlims.widths
            axspace_to_vpspace(x,y) = let scale = [vp_xw / ax_xw, vp_yw / ax_yw]
                scale .* ([x, y] + [ax_xo, ax_yo]) + [vp_xo, vp_yo]
            end
            vp_l, vp_b = axspace_to_vpspace(x,y)
            vp_r, vp_t = axspace_to_vpspace(x+ax_xw/10,y+ax_yw/10)
            BBox(vp_l, vp_r, vp_b, vp_t)
        end
        a = Axis(fig; bbox)
        scatter!(a, rand(n), rand(n))
    end
    display(fig)
    fig
end

This was pretty tricky though, and might go wrong with unitful or logarithmic axes. Would it be theoretically possible to just do like this?

xs = 1:5:30
ys = xs .^ 2
scatter(xs, ys; marker=[scatter(rand(50), rand(50)).axis for _ in xs])

Perhaps with custom marker shape · Issue #422 · MakieOrg/Makie.jl · GitHub, or is Axis the wrong kind of thing so it couldn’t ever be a marker?

Axis isn’t a compatible object for markers, but one could make the placement function more robust, so it works with log axes as well. That means also lifting on the underlying axis’ transformation function.

1 Like