Open DanielVandH opened 1 month ago
This is generic to all Block
s I think, maybe we could inject a keyword check somewhere? But that seems incompatible with methods like initialize_block!(::Axis; palette) got unsupported keyword argument "blahblah"
, since you'd have to know that method takes the palette
kwarg.
Can it be tried in any of the earlier calls like create_axis_for_plot
(just going off the stacktrace anyway)?
I actually don't want the keywords in the initialize_block!
thing anymore... I think I only did it because I didn't know how else to pipe that palette through, but at the time it wasn't clear anyway how one should do that
One quick solution specific to Axis
(that I'm sure there are problems with since I'm in unfamiliar territory here 😅) is to define
MakieCore._valid_attributes(::Type{<:Axis}) = keys(_attribute_docs(Axis))
MakieCore._is_block(::Type{<:Axis}) = true
function validate_axis_attributes(attributes::Dict)
nameset = _attribute_docs(Axis)
unknown = setdiff(keys(attributes), nameset)
if !isempty(unknown)
throw(MakieCore.InvalidAttributeError(Axis, unknown))
end
return
end
and then put validate_axis_attributes
at the top of create_axis_for_plot
:
function create_axis_for_plot(figure::Figure, plot::AbstractPlot, attributes::Dict)
axis_kw = extract_attributes(attributes, :axis)
validate_axis_attributes(axis_kw)
AxType = if haskey(axis_kw, :type)
pop!(axis_kw, :type)
else
preferred_axis_type(plot)
end
if AxType == FigureOnly # For FigureSpec, which creates Axes dynamically
return nothing
end
bbox = pop!(axis_kw, :bbox, nothing)
set_axis_attributes!(AxType, axis_kw, plot)
return _block(AxType, figure, [], axis_kw, bbox)
end
Reusing InvalidAttributeError
like this meant I needed to adjust InvalidAttributeError
a bit (further adjustments would be needed to not call Axis
a plot type too)
_valid_attributes(p) = attribute_names(p)
_is_block(_) = false
function Base.showerror(io::IO, i::InvalidAttributeError)
n = length(i.attributes)
print(io, "Invalid attribute$(n > 1 ? "s" : "") ")
for (j, att) in enumerate(i.attributes)
j > 1 && print(io, j == length(i.attributes) ? " and " : ", ")
printstyled(io, att; color = :red, bold = true)
end
print(io, " for plot type ")
printstyled(io, i.plottype; color = :blue, bold = true)
println(io, ".")
nameset = sort(string.(collect(_valid_attributes(i.plottype))))
println(io)
println(io, "The available plot attributes for $(i.plottype) are:")
println(io)
print_columns(io, nameset; cols = displaysize(stderr)[2], rows_first = true)
if !_is_block(i.plottype)
allowlist = attribute_name_allowlist()
println(io)
println(io)
println(io, "Generic attributes are:")
println(io)
print_columns(io, sort([string(a) for a in allowlist]); cols = displaysize(stderr)[2], rows_first = true)
println(io)
else
println(io)
println(io)
end
end
This shows
julia> scatter([1.0], [1.0], axis = (; blahblah = "1.0")) # should show suggestions
ERROR: Invalid attribute blahblah for plot type Axis.
The available plot attributes for Axis are:
alignmode height subtitlefont titlefont xaxisposition xlabelsize xminorticksvisible xticklabelalign xticksmirrored ygridvisible yminorgridstyle ypanlock yticklabelpad ytrimspine
aspect leftspinecolor subtitlegap titlegap xgridcolor xlabelvisible xminortickwidth xticklabelcolor xticksvisible ygridwidth yminorgridvisible yrectzoom yticklabelrotation yzoomkey
autolimitaspect leftspinevisible subtitlelineheight titlelineheight xgridstyle xminorgridcolor xpankey xticklabelfont xtickwidth ylabel yminorgridwidth yreversed yticklabelsize yzoomlock
backgroundcolor limits subtitlesize titlesize xgridvisible xminorgridstyle xpanlock xticklabelpad xtrimspine ylabelcolor yminortickalign yscale yticklabelspace zoombutton
bottomspinecolor panbutton subtitlevisible titlevisible xgridwidth xminorgridvisible xrectzoom xticklabelrotation xzoomkey ylabelfont yminortickcolor ytickalign yticklabelsvisible
bottomspinevisible rightspinecolor tellheight topspinecolor xlabel xminorgridwidth xreversed xticklabelsize xzoomlock ylabelpadding yminorticks ytickcolor yticks
dim1_conversion rightspinevisible tellwidth topspinevisible xlabelcolor xminortickalign xscale xticklabelspace yautolimitmargin ylabelrotation yminorticksize ytickformat yticksize
dim2_conversion spinewidth title valign xlabelfont xminortickcolor xtickalign xticklabelsvisible yaxisposition ylabelsize yminorticksvisible yticklabelalign yticksmirrored
flip_ylabel subtitle titlealign width xlabelpadding xminorticks xtickcolor xticks ygridcolor ylabelvisible yminortickwidth yticklabelcolor yticksvisible
halign subtitlecolor titlecolor xautolimitmargin xlabelrotation xminorticksize xtickformat xticksize ygridstyle yminorgridcolor ypankey yticklabelfont ytickwidth
Stacktrace:
[1] validate_axis_attributes(attributes::Dict{Symbol, Any})
@ Makie c:\Users\danjv\.julia\dev\Makie.jl\src\figureplotting.jl:101
[2] create_axis_for_plot(figure::Figure, plot::Scatter{Tuple{Vector{Point{2, Float64}}}}, attributes::Dict{Symbol, Any})
@ Makie c:\Users\danjv\.julia\dev\Makie.jl\src\figureplotting.jl:108
[3] create_axis_like(plot::Scatter{Tuple{Vector{Point{2, Float64}}}}, attributes::Dict{Symbol, Any}, ::Nothing)
@ Makie c:\Users\danjv\.julia\dev\Makie.jl\src\figureplotting.jl:211
[4] _create_plot(::Function, ::Dict{Symbol, Any}, ::Vector{Float64}, ::Vararg{Vector{Float64}})
@ Makie c:\Users\danjv\.julia\dev\Makie.jl\src\figureplotting.jl:329
[5] scatter(::Vector{Float64}, ::Vararg{Vector{Float64}}; kw::@Kwargs{axis::@NamedTuple{blahblah::String}})
@ MakieCore c:\Users\danjv\.julia\dev\Makie.jl\MakieCore\src\recipes.jl:449
[6] top-level scope
@ REPL[63]:1
Maybe something like this would generalise to Block
s in general if these checks were put in the appropriate places.. would probably address #4390 too.
That solution also unfortunately fails for calls like
ulia> Axis(fig[1,1],bad=2)
ERROR: MethodError: no method matching initialize_block!(::Axis; bad::Int64)
Closest candidates are:
initialize_block!(::Axis; palette) got unsupported keyword argument "bad"
@ Makie c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks\axis.jl:150
initialize_block!(::Label) got unsupported keyword argument "bad"
@ Makie c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks\label.jl:3
initialize_block!(::Toggle) got unsupported keyword argument "bad"
@ Makie c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks\toggle.jl:1
...
Stacktrace:
[1] kwerr(::@NamedTuple{bad::Int64}, ::Function, ::Axis)
@ Base .\error.jl:165
[2] _block(T::Type{…}, fig_or_scene::Figure, args::Vector{…}, kwdict::Dict{…}, bbox::Nothing; kwdict_complete::Bool)
@ Makie c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks.jl:371
[3] _block
@ c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks.jl:291 [inlined]
[4] #_block#1490
@ c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks.jl:259 [inlined]
[5] _block(::Type{Axis}, ::GridPosition; kwargs::@Kwargs{bad::Int64})
@ Makie c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks.jl:253
[6] _block
@ c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks.jl:246 [inlined]
[7] #_#1488
@ c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks.jl:237 [inlined]
[8] top-level scope
@ REPL[67]:1
Some type information was truncated. Use `show(err)` to see complete types.
so I guess it needs to be injected into _block
somewhere, but I have little idea about what's going on in this part. I'm guessing
@ c:\Users\danjv\.julia\dev\Makie.jl\src\makielayout\blocks.jl:291 [inlined]
would be the place to do it when attribute_kwargs
is constructed.
]st -m Makie
)]activate --temp; add Makie
)Is it possible to allow suggestions for allowed keyword arguments to be shown here?