From 3ed50bbf0fbc028026cbe3d4a8ff191f4ec07906 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Mar 2020 00:22:55 +0100 Subject: [PATCH 1/5] make type recipes work for vectors --- src/series.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/series.jl b/src/series.jl index bba2f313..4f66da77 100644 --- a/src/series.jl +++ b/src/series.jl @@ -181,11 +181,11 @@ function _apply_type_recipe(plotattributes, v::AbstractArray) isempty(skipmissing(v)) && return Float64[] x = first(skipmissing(v)) args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args - if length(args) == 2 && typeof(args[1]) <: Function && typeof(args[2]) <: Function + if length(args) == 2 && all(arg -> arg isa Function, args) numfunc, formatter = args Formatted(map(numfunc, v), formatter) else - v + RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1] end end From 89e271bd912187e5193e670b28129bd124fa04e5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Mar 2020 01:23:46 +0100 Subject: [PATCH 2/5] reverse type recipe order --- src/series.jl | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/series.jl b/src/series.jl index 4f66da77..edc1053b 100644 --- a/src/series.jl +++ b/src/series.jl @@ -178,15 +178,19 @@ _apply_type_recipe(plotattributes, v) = RecipesBase.apply_recipe(plotattributes, # This sort of recipe should return a pair of functions... one to convert to number, # and one to format tick values. function _apply_type_recipe(plotattributes, v::AbstractArray) - isempty(skipmissing(v)) && return Float64[] - x = first(skipmissing(v)) - args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args - if length(args) == 2 && all(arg -> arg isa Function, args) - numfunc, formatter = args - Formatted(map(numfunc, v), formatter) - else - RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1] + # First we try to apply an array type recipe. + w = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1] + # If the type did not change try it element-wise + if v == w + isempty(skipmissing(v)) && return Float64[] + x = first(skipmissing(v)) + args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args + if length(args) == 2 && all(arg -> arg isa Function, args) + numfunc, formatter = args + return Formatted(map(numfunc, v), formatter) + end end + return w end # # special handling for Surface... need to properly unwrap and re-wrap From b60007cde9d9404355deb91d6f55eb47ba47b2a2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Mar 2020 01:28:29 +0100 Subject: [PATCH 3/5] update comment --- src/series.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/series.jl b/src/series.jl index edc1053b..787c7200 100644 --- a/src/series.jl +++ b/src/series.jl @@ -180,7 +180,7 @@ _apply_type_recipe(plotattributes, v) = RecipesBase.apply_recipe(plotattributes, function _apply_type_recipe(plotattributes, v::AbstractArray) # First we try to apply an array type recipe. w = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1] - # If the type did not change try it element-wise + # If it did not change try it element-wise if v == w isempty(skipmissing(v)) && return Float64[] x = first(skipmissing(v)) From f606f083a4ad45a51f5bd3f3c58964837c56085f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Mar 2020 01:43:42 +0100 Subject: [PATCH 4/5] fix for vectors containing missing --- src/series.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/series.jl b/src/series.jl index 787c7200..44fd7b95 100644 --- a/src/series.jl +++ b/src/series.jl @@ -180,14 +180,16 @@ _apply_type_recipe(plotattributes, v) = RecipesBase.apply_recipe(plotattributes, function _apply_type_recipe(plotattributes, v::AbstractArray) # First we try to apply an array type recipe. w = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1] - # If it did not change try it element-wise - if v == w + # If the type did not change try it element-wise + if typeof(v) == typeof(w) isempty(skipmissing(v)) && return Float64[] x = first(skipmissing(v)) args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args if length(args) == 2 && all(arg -> arg isa Function, args) numfunc, formatter = args return Formatted(map(numfunc, v), formatter) + else + return v end end return w From 96181b8c48210dfe21cf3f2266695a757a7a42ae Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Mar 2020 16:27:08 +0100 Subject: [PATCH 5/5] only apply axis attributes in type recipes to current axis --- src/series.jl | 56 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/series.jl b/src/series.jl index 44fd7b95..7e51043f 100644 --- a/src/series.jl +++ b/src/series.jl @@ -172,12 +172,18 @@ end # this should catch unhandled "series recipes" and error with a nice message @recipe f(::Type{V}, x, y, z) where {V<:Val} = error("The backend must not support the series type $V, and there isn't a series recipe defined.") -_apply_type_recipe(plotattributes, v) = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1] +function _apply_type_recipe(plotattributes, v, letter) + _handle_axis_args!(plotattributes) + rdvec = RecipesBase.apply_recipe(plotattributes, typeof(v), v) + _handle_axis_args!(plotattributes, letter) + return rdvec[1].args[1] +end # Handle type recipes when the recipe is defined on the elements. # This sort of recipe should return a pair of functions... one to convert to number, # and one to format tick values. -function _apply_type_recipe(plotattributes, v::AbstractArray) +function _apply_type_recipe(plotattributes, v::AbstractArray, letter) + _handle_axis_args!(plotattributes) # First we try to apply an array type recipe. w = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1] # If the type did not change try it element-wise @@ -185,6 +191,7 @@ function _apply_type_recipe(plotattributes, v::AbstractArray) isempty(skipmissing(v)) && return Float64[] x = first(skipmissing(v)) args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args + _handle_axis_args!(plotattributes, letter) if length(args) == 2 && all(arg -> arg isa Function, args) numfunc, formatter = args return Formatted(map(numfunc, v), formatter) @@ -192,6 +199,7 @@ function _apply_type_recipe(plotattributes, v::AbstractArray) return v end end + _handle_axis_args!(plotattributes, letter) return w end @@ -212,16 +220,44 @@ end # end # don't do anything for ints or floats -_apply_type_recipe(plotattributes, v::AbstractArray{T}) where {T<:Union{Integer,AbstractFloat}} = v +_apply_type_recipe(plotattributes, v::AbstractArray{T}, letter) where {T<:Union{Integer,AbstractFloat}} = v + +# axis args in type recipes should only be applied to the current axis +function _handle_axis_args!(plotattributes, letter) + if letter in (:x, :y, :z) + replaceAliases!(plotattributes, _keyAliases) + for (k, v) in plotattributes + if haskey(_axis_defaults, k) + pop!(plotattributes, k) + lk = Symbol(letter, k) + haskey(plotattributes, lk) || (plotattributes[lk] = v) + end + end + end +end + +# axis args before type recipes should still be mapped to all axes +function _handle_axis_args!(plotattributes) + replaceAliases!(plotattributes, _keyAliases) + for (k, v) in plotattributes + if haskey(_axis_defaults, k) + pop!(plotattributes, k) + for letter in (:x, :y, :z) + lk = Symbol(letter, k) + haskey(plotattributes, lk) || (plotattributes[lk] = v) + end + end + end +end # handle "type recipes" by converting inputs, and then either re-calling or slicing @recipe function f(x, y, z) did_replace = false - newx = _apply_type_recipe(plotattributes, x) + newx = _apply_type_recipe(plotattributes, x, :x) x === newx || (did_replace = true) - newy = _apply_type_recipe(plotattributes, y) + newy = _apply_type_recipe(plotattributes, y, :y) y === newy || (did_replace = true) - newz = _apply_type_recipe(plotattributes, z) + newz = _apply_type_recipe(plotattributes, z, :z) z === newz || (did_replace = true) if did_replace newx, newy, newz @@ -231,9 +267,9 @@ _apply_type_recipe(plotattributes, v::AbstractArray{T}) where {T<:Union{Integer, end @recipe function f(x, y) did_replace = false - newx = _apply_type_recipe(plotattributes, x) + newx = _apply_type_recipe(plotattributes, x, :x) x === newx || (did_replace = true) - newy = _apply_type_recipe(plotattributes, y) + newy = _apply_type_recipe(plotattributes, y, :y) y === newy || (did_replace = true) if did_replace newx, newy @@ -242,7 +278,7 @@ end end end @recipe function f(y) - newy = _apply_type_recipe(plotattributes, y) + newy = _apply_type_recipe(plotattributes, y, :y) if y !== newy newy else @@ -255,7 +291,7 @@ end @recipe function f(v1, v2, v3, v4, vrest...) did_replace = false newargs = map(v -> begin - newv = _apply_type_recipe(plotattributes, v) + newv = _apply_type_recipe(plotattributes, v, :unknown) if newv !== v did_replace = true end