MakieOrg / Makie.jl

Interactive data visualizations and plotting in Julia
https://docs.makie.org/stable
MIT License
2.43k stars 312 forks source link

Default xlabel and ylabel in recipe #1524

Open tkf opened 2 years ago

tkf commented 2 years ago

How do I set default x and y labels in the full recipe? I'm trying to do something similar to xlabel --> "default X label" in RecipesBase.jl. Here's a code sample that didn't work with Makie v0.15.3

module MyRecipe

using Makie

struct MyPlotData
    x::Vector{Float64}
    y::Vector{Float64}
    xlabel::String
    ylabel::String
end

@recipe(MyPlot, data) do scene
    # Errors since `data` is not in scope:
    # Attributes(axis = (xlabel = data.xlabel, ylabel = data.ylabel))

    # But setting labels here seem to not work anyway:
    # Attributes(xlabel = "default X", ylabel = "default Y")
    # Attributes(axis = (xlabel = "default X", ylabel = "default Y"))

    Attributes()
end

function Makie.plot!(myplot::MyPlot{<:Tuple{<:MyPlotData}})
    data = myplot[1][]
    axis = (xlabel = data.xlabel, ylabel = data.ylabel)

    # scatter!(myplot, data.x, data.y; axis = axis)
    sc = scatter!(myplot, data.x, data.y)

    # These does not work:
    # sc.axis = axis
    # sc.xlabel = data.xlabel
    # sc.ylabel = data.ylabel
    # myplot.axis = axis
    # myplot.xlabel = data.xlabel
    # myplot.ylabel = data.ylabel

    # Throws a method error:
    # xlabel!(myplot, data.xlabel)
    # ylabel!(myplot, data.ylabel)

    return myplot
end

randomdata(n = 100) = MyPlotData(randn(n), randn(n), "X axis", "Y axis")

function demo()
    data = randomdata()
    myplot(data)
end

end  # module MyRecipe

import CairoMakie
MyRecipe.demo()

I looked at https://makie.juliaplots.org/stable/documentation/recipes/ but it is not clear if this is supported. The only "workaround" I've found was to bypass the recipe system and just define Makie.plot(::MyPlotData) directly. #1148 may be somewhat related but I'm not sure.

I think it is either a documentation request or a feature request, depending on if this is already possible.

Krastanov commented 2 years ago

I do not think there is yet a way to modify an axis attribute from inside a plot recipe (which only touches a set of plots inside of an axis without touching the axis itself). My understanding is that it is this way for now because it is not clear what should happen if two recipes that are used together both want to modify the axis.

This seems like a related issue https://github.com/JuliaPlots/Makie.jl/issues/379