warn on recipe aliases

This commit is contained in:
Daniel Schwabeneder 2020-03-27 13:44:39 +01:00
parent 932d0da73d
commit 0c2d80841c
4 changed files with 64 additions and 4 deletions

View File

@ -460,6 +460,24 @@ is_axis_attr_noletter(k) = haskey(_axis_defaults, k)
RecipesBase.is_key_supported(k::Symbol) = is_attr_supported(k) RecipesBase.is_key_supported(k::Symbol) = is_attr_supported(k)
const _internal_args =
[:plot_object, :series_plotindex, :markershape_to_add, :letter, :idxfilter]
const _magic_axis_args = [:axis, :tickfont, :guidefont]
const _magic_subplot_args = [:titlefont, :legendfont, :legendtitlefont, ]
const _magic_series_args = [:line, :marker, :fill]
function is_default_attribute(k::Symbol)
k in _internal_args && return true
k in _all_args && return true
is_axis_attr(k) && return true
is_axis_attr_noletter(k) && return true
k in _magic_axis_args && return true
k in _magic_subplot_args && return true
k in _magic_series_args && return true
Symbol(chop(string(k); head = 1, tail = 0)) in _magic_axis_args && return true
return false
end
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
makeplural(s::Symbol) = Symbol(string(s,"s")) makeplural(s::Symbol) = Symbol(string(s,"s"))
@ -1017,6 +1035,16 @@ function preprocessArgs!(plotattributes::AKW, replace_aliases = true)
end end
end end
end end
# handle axes guides
if haskey(plotattributes, :guide)
guide = pop!(plotattributes, :guide)
for letter in (:x, :y, :z)
guide_sym = Symbol(letter, :guide)
if !is_explicit(plotattributes, guide_sym)
plotattributes[guide_sym] = guide
end
end
end
# handle line args # handle line args
for arg in wraptuple(pop_kw!(plotattributes, :line, ())) for arg in wraptuple(pop_kw!(plotattributes, :line, ()))

View File

@ -1,4 +1,26 @@
# Error for aliases used in recipes
function warn_on_recipe_aliases!(plotattributes, recipe_type, args...)
for k in keys(plotattributes)
if !is_default_attribute(k)
dk = get(_keyAliases, k, k)
if k !== dk
@warn "Attribute alias `$k` detected in the $recipe_type recipe defined for the signature $(signature_string(Val{recipe_type}, args...)). To ensure expected behavior it is recommended to use the default attribute `$dk`."
end
plotattributes[dk] = pop_kw!(plotattributes, k)
end
end
end
warn_on_recipe_aliases!(v::AbstractVector, recipe_type, args) =
foreach(x -> warn_on_recipe_aliases!(x, recipe_type, args), v)
warn_on_recipe_aliases!(rd::RecipeData, recipe_type, args) =
warn_on_recipe_aliases!(rd.plotattributes, recipe_type, args)
function signature_string(::Type{Val{:user}}, args...)
return string("(::", join(string.(typeof.(args)), ", ::"), ")")
end
signature_string(::Type{Val{:type}}, T) = "(::Type{$T}, ::$T)"
signature_string(::Type{Val{:plot}}, st) = "(::Type{Val{:$st}}, ::AbstractPlot)"
signature_string(::Type{Val{:series}}, st) = "(::Type{Val{:$st}}, x, y, z)"
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# preprocessing # preprocessing
@ -82,7 +104,11 @@ function _process_userrecipes(plt::Plot, plotattributes::AKW, args)
if isempty(next_series.args) if isempty(next_series.args)
_process_userrecipe(plt, kw_list, next_series) _process_userrecipe(plt, kw_list, next_series)
else else
rd_list = RecipesBase.apply_recipe(next_series.plotattributes, next_series.args...) rd_list = RecipesBase.apply_recipe(
next_series.plotattributes,
next_series.args...
)
warn_on_recipe_aliases!(rd_list, :user, next_series.args)
prepend!(still_to_process,rd_list) prepend!(still_to_process,rd_list)
end end
end end
@ -184,6 +210,7 @@ function _process_plotrecipe(plt::Plot, kw::AKW, kw_list::Vector{KW}, still_to_p
st = kw[:seriestype] st = kw[:seriestype]
st = kw[:seriestype] = get(_typeAliases, st, st) st = kw[:seriestype] = get(_typeAliases, st, st)
datalist = RecipesBase.apply_recipe(kw, Val{st}, plt) datalist = RecipesBase.apply_recipe(kw, Val{st}, plt)
warn_on_recipe_aliases!(datalist, :plot, st)
for data in datalist for data in datalist
preprocessArgs!(data.plotattributes, false) preprocessArgs!(data.plotattributes, false)
if data.plotattributes[:seriestype] == st if data.plotattributes[:seriestype] == st
@ -408,7 +435,9 @@ function _process_seriesrecipe(plt::Plot, plotattributes::AKW)
else else
# get a sub list of series for this seriestype # get a sub list of series for this seriestype
datalist = RecipesBase.apply_recipe(plotattributes, Val{st}, plotattributes[:x], plotattributes[:y], plotattributes[:z]) x, y, z = plotattributes[:x], plotattributes[:y], plotattributes[:z]
datalist = RecipesBase.apply_recipe(plotattributes, Val{st}, x, y, z)
warn_on_recipe_aliases!(datalist, :series, st)
# assuming there was no error, recursively apply the series recipes # assuming there was no error, recursively apply the series recipes
for data in datalist for data in datalist

View File

@ -1261,8 +1261,8 @@ end
yflip := true yflip := true
aspect_ratio := 1 aspect_ratio := 1
rs, cs, zs = findnz(z.surf) rs, cs, zs = findnz(z.surf)
xlim := ignorenan_extrema(cs) xlims := ignorenan_extrema(cs)
ylim := ignorenan_extrema(rs) ylims := ignorenan_extrema(rs)
if plotattributes[:markershape] == :none if plotattributes[:markershape] == :none
markershape := :circle markershape := :circle
end end

View File

@ -178,6 +178,7 @@ end
function _apply_type_recipe(plotattributes, v, letter) function _apply_type_recipe(plotattributes, v, letter)
_preprocess_axis_args!(plotattributes, letter) _preprocess_axis_args!(plotattributes, letter)
rdvec = RecipesBase.apply_recipe(plotattributes, typeof(v), v) rdvec = RecipesBase.apply_recipe(plotattributes, typeof(v), v)
warn_on_recipe_aliases!(plotattributes, :type, typeof(v))
_postprocess_axis_args!(plotattributes, letter) _postprocess_axis_args!(plotattributes, letter)
return rdvec[1].args[1] return rdvec[1].args[1]
end end
@ -189,11 +190,13 @@ function _apply_type_recipe(plotattributes, v::AbstractArray, letter)
_preprocess_axis_args!(plotattributes, letter) _preprocess_axis_args!(plotattributes, letter)
# First we try to apply an array type recipe. # First we try to apply an array type recipe.
w = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1] w = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1]
warn_on_recipe_aliases!(plotattributes, :type, typeof(v))
# If the type did not change try it element-wise # If the type did not change try it element-wise
if typeof(v) == typeof(w) if typeof(v) == typeof(w)
isempty(skipmissing(v)) && return Float64[] isempty(skipmissing(v)) && return Float64[]
x = first(skipmissing(v)) x = first(skipmissing(v))
args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args
warn_on_recipe_aliases!(plotattributes, :type, typeof(x))
_postprocess_axis_args!(plotattributes, letter) _postprocess_axis_args!(plotattributes, letter)
if length(args) == 2 && all(arg -> arg isa Function, args) if length(args) == 2 && all(arg -> arg isa Function, args)
numfunc, formatter = args numfunc, formatter = args