MakieLayout.jl

MakieLayout.jl brings a new 2D Axis LAxis and grid layouting with GridLayout to Makie.jl. You can build complex layouts by nesting GridLayouts. You can specify many visual parameters like row and column widths, the gap sizes between the rows and columns, or paddings. 2D axes have many more parameters like titles, labels, ticks, their sizes and colors and alignments, etc. All of these parameters are Observables and the layout updates itself automatically when you change relevant ones.

As a starting point, here's an example how you can iteratively build a plot out of its parts:

using MakieLayout
using Makie
using AbstractPlotting: px

# layoutscene is a convenience function that creates a Scene and a GridLayout
# that are already connected correctly and with Outside alignment
scene, layout = layoutscene(30, resolution = (1200, 900),
    backgroundcolor = RGBf0(0.98, 0.98, 0.98))

record(scene, "example_plot_buildup.mp4", framerate=1) do io
    ax1 = layout[1, 1] = LAxis(scene, title = "Group 1")
    ax2 = layout[1, 2] = LAxis(scene, title = "Group 2")
    sca1 = scatter!(ax1, randn(100, 2), markersize = 10px, color = :red)
    sca2 = scatter!(ax1, randn(100, 2) .+ 1, markersize = 10px, marker = 'x',
        color = :blue)
    sca3 = scatter!(ax2, randn(100, 2) .+ 2, markersize = 10px, marker = '□',
        color = :green)
    sca4 = scatter!(ax2, randn(100, 2) .+ 3, markersize = 10px, color = :orange)

    linkaxes!(ax1, ax2)
    autolimits!(ax1)

    leg = LLegend(scene, [sca1, sca2, sca3, sca4], ["alpha", "beta", "gamma", "delta"],
        orientation = :horizontal, height = Auto(true), width = Auto(false))
    layout[2, :] = leg

    ax3 = layout[:, end + 1] = LAxis(scene)

    ts = 0:0.01:20
    cmap = Node(:viridis)
    spiral = lines!(ax3, sin.(ts) .* ts, ts, color = ts, colormap = cmap,
        linewidth = 4)

    ax3.xlabel = "Horizontal"
    ax3.ylabel = "Vertical"

    cbar = layout[:, end + 1] = LColorbar(scene, spiral, width = 30)
    cbar.height = Relative(0.66)

    cmap[] = :inferno

    subgrid = layout[end + 1, :] = GridLayout()

    ax4 = subgrid[1, 1] = LAxis(scene)
    heatmap!(ax4, randn(50, 30))
    tightlimits!(ax4)

    sliders = [LSlider(scene) for _ in 1:3]
    labels = [LText(scene, l, halign = :left) for l in ("Adjust", "Refresh", "Compute")]
    slidergrid = subgrid[1, 0] = grid!(hcat(labels, sliders), height = Auto(false))

    ax5 = subgrid[1, 0] = LAxis(scene)
    heatmap!(ax5, randn(50, 30), colormap = :blues)
    tightlimits!(ax5)

    colsize!(subgrid, 2, Relative(0.5))

    ax4.yaxisposition = :right
    ax4.yticklabelalign = (:left, :center)

    suptitle = layout[0, :] = LText(scene, "MakieLayout.jl")
    suptitle.textsize = 40

    foreach(tight_ticklabel_spacing!, LAxis, layout)
end