# Axis-generating functions in Makie

**URL:** <https://discourse.julialang.org/t/axis-generating-functions-in-makie/99558>\
**Category:** Visualization\
**Tags:** question, makie\
**Created:** [May 29, 2023, 12:31pm UTC](https://discourse.julialang.org/t/axis-generating-functions-in-makie/99558 "2023-05-29T12:31:35Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 29, 2023, 12:31pm UTC](https://discourse.julialang.org/t/axis-generating-functions-in-makie/99558/1 "2023-05-29T12:31:35Z")

</div>

I would like to organize some commonly used plots into functions. Eg

```julia
function makie_plot_posterior_check(figure, label, data, predicted;
                                    scatter_color = alphacolor(colorant"black", 0.7),
                                    diagonal_color = colorant"gray")
    ax = Makie.Axis(figure; xlabel = "$(label) data", ylabel = "$(label) (posterior mean)")
    Makie.ablines!(ax, [0], [1]; color = diagonal_color)
    Makie.scatter!(ax, data, predicted; color = scatter_color)
    figure
end

```

which I would then use as eg

```julia
f = Figure()
makie_plot_posterior_check(f[1,1], "male work hours", data.n1, predicted.n1)
save("output_path.svg", f)

```

The idea is that I may make a single plot of this kind, or a grid of them, etc, using this function.

But I find it tedious to have to pass in the figure/scene.

Is it possible/idiomatic to create an `Axis` in Makie, then _later on_ attach it to a `Figure` (or scene)?

Or am I organizing my code the wrong way?

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [May 29, 2023, 1:12pm UTC](https://discourse.julialang.org/t/axis-generating-functions-in-makie/99558/2 "2023-05-29T13:12:58Z")

</div>

> [@Tamas\_Papp](#):
>
> Is it possible/idiomatic to create an `Axis` in Makie, then _later on_ attach it to a `Figure` (or scene)?

This is not (yet) supported. Or is it @jules ?

* * *

I wonder if it would be possible to create a `Lazy<:Makie.Block` that allows to wrap any other `Block` with

```julia
lazyax = Lazy(Axis, kwargs...)
# or maybe with a macro
lazyax = @lazy Axis(kwargs ...)

```

and that when inserted into a `GridLayout` resolves all the “recorded” plotting calls?

Assuming that could work, the code could be simplified to

```julia
function makie_plot_posterior_check(label, data, predicted;
                                    scatter_color = alphacolor(colorant"black", 0.7),
                                    diagonal_color = colorant"gray")
    ax = @lazy Makie.Axis(xlabel = "$(label) data", ylabel = "$(label) (posterior mean)")
    Makie.ablines!(ax, [0], [1]; color = diagonal_color)
    Makie.scatter!(ax, data, predicted; color = scatter_color)
    ax
end

f = Figure()
f[1,1] = makie_plot_posterior_check("male work hours", data.n1, predicted.n1)
save("output_path.svg", f)

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [May 29, 2023, 2:23pm UTC](https://discourse.julialang.org/t/axis-generating-functions-in-makie/99558/3 "2023-05-29T14:23:30Z")

</div>

Attaching an Axis (or any plot object) to a Figure/Scene after creation is not possible currently.

What I do currently, and which we haven’t had time to consolidate into a real recipe-like API is something like this, where you can plot your recipe into any gridlayout position. If no Figure exists, yet, it is created automatically. It would be nice to have this at some point with full tie-in to the theming system, conversion system, etc.

In this example, you only need to define `compositeplot` once and can reuse it for all plotting functions, then one forwarding method of the plotting function and one implementation method.

There are still things to work out, like what each method should return etc. but it might be a start for you.

```julia
using CairoMakie

function compositeplot(func::Function, gp::Union{GridPosition,GridSubposition}, args...; kwargs...)
    f = Makie.get_top_parent(gp)
    f isa Figure || error("Parent of GridPosition must be a Figure not a $(typeof(f))")
    g = Makie.GridLayoutBase.get_layout_at!(gp; createmissing = true)
    result = func(f, g, args...; kwargs...)
    return f, result
end

function compositeplot(func::Function, args...; figure = (;), kwargs...)
    f = Figure(; figure...)
    result = func(f[1, 1], args...; kwargs...)
    return f, result
end

myplot(args...; kwargs...) = compositeplot(myplot, args...; kwargs...)

function myplot(f::Figure, g::GridLayout, data::Vector{Float64}; colormap = :RdBu)
    ax = Axis(g[1, 1], title = "$colormap")
    sc = scatter!(ax, data; color = randn(length(data)), colormap)
    cb = Colorbar(g[2, 1], sc, vertical = false)
    return (; axis = ax, colorbar = cb, scatterlines = sc)
end

fig, stuff = myplot(cumsum(randn(100)))
myplot(fig[2, 1], cumsum(randn(100)); colormap = :inferno)
_, morestuff = myplot(fig[1:2, 2], cumsum(randn(100)); colormap = :Blues)
morestuff.colorbar.label = "Hi from the label"
fig

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/a/b/abaa278590729008da922e8f3d718ab8eaffa256.jpeg)
