Align axes on different grids

Hello,

I want to create a figure using Makie.jl that aligns different axes in different layouts. For example, I have the following code

using CairoMakie
CairoMakie.activate!(type = "svg", pt_per_unit = 1.25)

λ_color = :dodgerblue3
ϵ_color = :crimson

fig = Figure(size=(430, 0.85*430))

Label(fig[1, 1], "Liouvillian", tellwidth=false, tellheight=true)
Label(fig[1, 2], "Propagator", tellwidth=false, tellheight=true)

grid_λ = GridLayout(fig[2, 1], alignmode=Outside(15))
grid_ϵ = GridLayout(fig[2, 2], alignmode=Outside(15))

box_λ = Box(fig[2, 1], cornerradius = 10, color = (λ_color, 0.25), strokecolor = :transparent)
box_ϵ = Box(fig[2, 2], cornerradius = 10, color = (ϵ_color, 0.25), strokecolor = :transparent)

# move the boxes back so the Axis background polys are in front of them
Makie.translate!(box_λ.blockscene, 0, 0, -100)
Makie.translate!(box_ϵ.blockscene, 0, 0, -100)

ax_λ = Axis(grid_λ[1, 1], ylabel=L"\mathrm{Im}(\lambda)")
ax_ϵ = Axis(grid_ϵ[1, 1], ylabel=L"\mathrm{Im}(\epsilon)")
ax_λ_gap = Axis(grid_λ[2, 1], xlabel=L"\mathrm{Re}(\lambda)", ylabel=L"\mathrm{Im}(\lambda)")
ax_ϵ_gap = Axis(grid_ϵ[2, 1], xlabel=L"\mathrm{Re}(\epsilon)", ylabel=L"\mathrm{Im}(\epsilon)")

# --- Limits and aspect ratios ---

ylims!(ax_λ_gap, -100, 100)
xlims!(ax_ϵ_gap, 0.88, 1.01)
ylims!(ax_ϵ_gap, -0.25, 0.25)

rowsize!(grid_λ, 1, Aspect(1, 1))
rowsize!(grid_λ, 2, Aspect(1, 1))
rowsize!(grid_ϵ, 1, Aspect(1, 1))
rowsize!(grid_ϵ, 2, Aspect(1, 1))

rowgap!(grid_λ, 8)
rowgap!(grid_ϵ, 8)
rowgap!(fig.layout, 2)
colgap!(fig.layout, 5)

# save(joinpath(@__DIR__, "figures/eigenvalues_sketch.pdf"), fig, pt_per_unit = 1)

fig

That generates the following image

However, the axes in the different columns are not exactly aligned. This can be seen by changing the labels in the various plots.

I was thinking to remove the grid layout implementation, and just use the figure internal layout, but I didn’t manage to do it.

That is indeed a bit tricky to set up. Generally, things that should align need to share gridlayout column or row edges. So you cannot have two separate gridlayouts with Outside alignment.

One thing I could come up with now is two make the borders of the boxes using empty rows and columns that are simply shrunk to fixed sizes, which makes specifying the positions a bit more annoying as everything needs to be shifted accordingly. At least it looks good:

λ_color = :dodgerblue3
ϵ_color = :crimson

fig = Figure(size=(430, 0.85*430))

Label(fig[1, 1:3], "Liouvillian", tellwidth=false, tellheight=true)
Label(fig[1, 4:6], "Propagator", tellwidth=false, tellheight=true)

box_λ = Box(fig[2:5, 1:3, Makie.GridLayoutBase.Outer()], cornerradius = 10, color = (λ_color, 0.25), strokecolor = :transparent)
box_ϵ = Box(fig[2:5, 4:6, Makie.GridLayoutBase.Outer()], cornerradius = 10, color = (ϵ_color, 0.25), strokecolor = :transparent)

# move the boxes back so the Axis background polys are in front of them
Makie.translate!(box_λ.blockscene, 0, 0, -100)
Makie.translate!(box_ϵ.blockscene, 0, 0, -100)

ax_λ = Axis(fig[3, 2], ylabel=L"\mathrm{Im}(\lambda)")
ax_ϵ = Axis(fig[3, 5], ylabel=L"\mathrm{Im}(\epsilon)")
ax_λ_gap = Axis(fig[4, 2], xlabel=L"\frac{\mathrm{Re}(\lambda)}{2}", ylabel=L"\mathrm{Im}(\lambda)")
ax_ϵ_gap = Axis(fig[4, 5], xlabel=L"\mathrm{Re}(\epsilon)", ylabel=L"\mathrm{Im}(\epsilon)")

# --- Limits and aspect ratios ---

ylims!(ax_λ_gap, -100, 100)
xlims!(ax_ϵ_gap, 0.88, 1.01)
ylims!(ax_ϵ_gap, -0.25, 0.25)

rowgap!(fig.layout, 2)
colgap!(fig.layout, 5)

border_size = 10

rowsize!(fig.layout, 2, border_size)
rowsize!(fig.layout, 5, border_size)

colsize!(fig.layout, 1, border_size)
colsize!(fig.layout, 3, border_size)
colsize!(fig.layout, 4, border_size)
colsize!(fig.layout, 6, border_size)

# save(joinpath(@__DIR__, "figures/eigenvalues_sketch.pdf"), fig, pt_per_unit = 1)

fig
1 Like

Thank you!

Just two things.

First, I don’t need to write Makie.GridLayoutBase.Outer().

Second, is there a way to specify the colgap in only certain columns, and not in the entire figure layout? For example I want the upper labels to be closer.

Ok I used rowgap!(fig.layout, 1, 2) that only changes the gap between the first and second rows. I think this is not documented.

First, I don’t need to write Makie.GridLayoutBase.Outer().

ah I didn’t notice I left that in from earlier attempts

Ok I used rowgap!(fig.layout, 1, 2) that only changes the gap between the first and second rows. I think this is not documented.

yeah that’s how to do it, if you want you could file a docstring PR, I think it’s shown in a bunch of places in Makie’s docs but might lack a central docstring in GridLayoutBase

1 Like