Visual connection between different axes in Makie.jl

Hello,

I have a figure generated with CairoMakie.jl. This figure contains two axes, something like


fig = Figure(size=(380, 220))

ax1 = Axis(fig[1, 1])
ax2 = Axis(fig[2, 1])


Now, I want to draw some lines (or even better a polygon with a filled color) between a point in ax1 and a point in ax2, but I don’t know how to do it.

Moreover, is it possible to directly link a point in ax1 to the upper corners of ax2?

There may be an easier way that I am not aware of, but when I did something similar in the past, I calculated the pixel-space coordinates of all involved points and plotted to the scene underlying the figure.
If noone else chimes in I can share my code in the coming days.
For your second question: what do mean by linking? Drawing a connecting line?

Yes, I mean just a simple line. More or less like an inset zoom effect, where the zoomed area is plotted in another axis

You can embed your two axes in a bigger axis like so:

using GLMakie 

fig = Figure()
gl = GridLayout(fig[1,1])
ax = Axis(fig[1,1])
xlims!(ax, 0, 1)
ylims!(ax, 0, 1)
ax1 = Axis(gl[1,1])
ax2 = Axis(gl[2,1])
hidedecorations!(ax)
hidespines!(ax)
scatterlines!(ax, [0.2,0.7] , [0.2,0.7]; overdraw = true)
fig

overdraw

I’ve never quite been able to figure out how to get all the coordinates of the subaxes without manually specifying them upfront though.

Ok this is a way. But I need the precise position of the end points. The first one has to be one point in ax1 and the second one has to be the upper-left corner of ax2 for example.

I did something similar here: Beautiful Makie

with

function posFig(ax, x; yoff=100, ylow = 15)
    o = ax.scene.viewport[].origin - Point2f(0, yoff)
    return Makie.project(ax.scene, Point2f(x, ylow)) + o
end

maybe you will need to do some minor changes.

2 Likes

Thanks!

I was able to do it by changing a bit your function and plotting the lines in the fig.scene, just like the link you gave me.

glad to read, please consider contributing here with a MWE of your solution, so that others can benefit in the future!


using CairoMakie

function posFig(ax, x, y)
    o = ax.scene.viewport[].origin
    return Makie.project(ax.scene, Point2f(x, y)) + o
end

fig = Figure()
ax1 = Axis(fig[1, 1:3])
ax2 = Axis(fig[2, 1])
ax3 = Axis(fig[2, 2])
ax4 = Axis(fig[2, 3])

pts1 = [posFig(ax1, 5, 2), posFig(ax2, 5, 5)]
pts2 = [posFig(ax1, 5, 2), posFig(ax3, 5, 5)]
pts3 = [posFig(ax1, 5, 2), posFig(ax4, 5, 5)]

lines!(fig.scene, getindex.(pts1, 1), getindex.(pts1, 2))
lines!(fig.scene, getindex.(pts2, 1), getindex.(pts2, 2))
lines!(fig.scene, getindex.(pts3, 1), getindex.(pts3, 2))

fig

3 Likes