Makie recipes on a Errorline like plot

Using the new Makie 0.24 recipe system, I want to create the StatsPlots.jl recipe for errorline (see original definition).

Here is a simplified version of the plume errorline.

This might be very simple but could not figure out how to do it properly from the docs.

What I want

  • Pass all regular Line attributes to the main line (color, alpha, linewidth, etc). I tried with Makie.shared_attributes but it does not work as expected (see usage example below).
  • For secondary lines (the plume lines), I want to have separate attributes (color, alpha, linewidth) with some default values (some equal to the main line, like color). Ideally, same as Lines attributes with secondary in front.
  • A parameter secondarylines to set the secondary lines to plot that can be a integer or vector.

Currently, I have the following code that works partially:

  • The default colors for main line is always black instead of default Makie colors.
  • Changing main line attributes like color or alpha throws an error since they are not expected attributes of SimpleErrorLine.
  • I use plt.x[] and plt.y[] to get the converted arguments, is there a better way? Will it work with interactive backends?
using CairoMakie
using StatsBase: mean

Makie.@recipe SimpleErrorLine (x, y) begin
    # arguments of Lines
    "Color for secondary elements (plume lines)"
    secondarycolor = :gray60 # how to have default matching main line color?
    "Alpha value of range"
    secondaryalpha = 0.1
    "Width of secondary lines"
    secondarylinewidth = 1
    # original argument
    "Number of plume lines to plot"
    secondarylines = 100 # could also be a vector
end

function Makie.plot!(plt::SimpleErrorLine)
    # Get converted arguments
    x = plt.x[]
    y = plt.y[]

    # Attributes for secondary lines
    secondarycolor = plt.secondarycolor
    secondaryalpha = plt.secondaryalpha
    secondarylinewidth = plt.secondarylinewidth
    secondarylines = plt.secondarylines[]

    # Attributes for main line
    valid_attributes = Makie.shared_attributes(plt, Lines)

    # Check y dimensions
    ndims(y) !== 2 && error("ndims(y) !== 2")
    size(y, 1) !== length(x) && error("size(y, 1) !== length(x)")

    # Compute center and distribution for each value of x
    y_central = mean(y; dims=2)
    y_central = dropdims(y_central; dims=2)

    if secondarylines isa Integer
        sub_idx = 1:secondarylines
    elseif secondarylines isa AbstractVector
        sub_idx = secondarylines
    else
        error("secondarylines must be Integer or AbstractVector, got $(typeof(secondarylines))")
    end

    for j in sub_idx
        lines!(plt, x, y[:, j], color=secondarycolor, alpha=secondaryalpha, linewidth=secondarylinewidth)
    end

    # Base line
    lines!(plt, valid_attributes, x, y_central)

    return nothing
end

Usage example:

xerror = 1:10
yerror = fill(NaN, 10, 100, 3)
for i = axes(yerror, 3)
    yerror[:, :, i] = collect(1:2:20) .+ rand(10, 100) .* 5 .* collect(1:2:20) .+ rand() * 100
end

fig = Figure()
ax = Axis(fig[1, 1])
simpleerrorline!(ax, 1:10, yerror[:, :, 1])
simpleerrorline!(ax, 1:10, yerror[:, :, 2], secondarycolor=:red, secondaryalpha=0.3, secondarylinewidth=2)
simpleerrorline!(ax, 1:10, yerror[:, :, 3], color=:blue, alpha=0.3, secondarylinewidth=2) # ERROR: Invalid attributes color and alpha
fig

I’m not a hundred percent sure right now how much this is supposed to be public or not, but we use Makie.documented_attributes(Lines)... internally. So:

Makie.@recipe SimpleErrorLine (x, y) begin
    Makie.documented_attributes(Lines)...
    # arguments of Lines
    "Color for secondary elements (plume lines)"
    secondarycolor = :gray60 # how to have default matching 

With that I get this plot from your example

Thanks! This solves part of the issue! (and far enough for what I want)

Now I wonder how to manage the secondary lines kwargs without conflict with main line et manually declaring each of them?
Plus inheriting some default of the main line.