diff --git a/src/UnitfulRecipes.jl b/src/UnitfulRecipes.jl index 67ef9df..3c91ef2 100644 --- a/src/UnitfulRecipes.jl +++ b/src/UnitfulRecipes.jl @@ -2,6 +2,7 @@ module UnitfulRecipes using RecipesBase using Unitful: Quantity, unit, ustrip, Unitful, dimension, Units +using Unitful: LogScaled, logunit, MixedUnits, Level, Gain, uconvert export @P_str const clims_types = (:contour, :contourf, :heatmap, :surface) @@ -10,11 +11,12 @@ const clims_types = (:contour, :contourf, :heatmap, :surface) Main recipe ==========# -@recipe function f(::Type{T}, x::T) where T <: AbstractArray{<:Union{Missing,<:Quantity}} +@recipe function f(::Type{T}, x::T) where T <: AbstractArray{<:Union{Missing,<:Quantity, <:LogScaled}} axisletter = plotattributes[:letter] # x, y, or z if (axisletter == :z) && get(plotattributes, :seriestype, :nothing) ∈ clims_types - u = get(plotattributes, :zunit, unit(eltype(x))) + # u = get(plotattributes, :zunit, unit(eltype(x))) + u = get(plotattributes, :zunit, eltype(x) <: LogScaled ? logunit(eltype(x)) : unit(eltype(x))) ustripattribute!(plotattributes, :clims, u) append_unit_if_needed!(plotattributes, :colorbar_title, u) end @@ -30,7 +32,7 @@ function fixaxis!(attr, x, axisletter) axisunit = Symbol(axisletter, :unit) # xunit, yunit, zunit axis = Symbol(axisletter, :axis) # xaxis, yaxis, zaxis # Get the unit - u = pop!(attr, axisunit, unit(eltype(x))) + u = pop!(attr, axisunit, _unit(x)) # If the subplot already exists with data, get its unit sp = get(attr, :subplot, 1) if sp ≤ length(attr[:plot_object]) && attr[:plot_object].n > 0 @@ -54,14 +56,14 @@ function fixaxis!(attr, x, axisletter) fixmarkersize!(attr) fixlinecolor!(attr) # Strip the unit - ustrip.(u, x) + _ustrip.(u, x) end # Recipe for (x::AVec, y::AVec, z::Surface) types const AVec = AbstractVector const AMat{T} = AbstractArray{T,2} where T @recipe function f(x::AVec, y::AVec, z::AMat{T}) where T <: Quantity - u = get(plotattributes, :zunit, unit(eltype(z))) + u = get(plotattributes, :zunit, _unit(z)) ustripattribute!(plotattributes, :clims, u) z = fixaxis!(plotattributes, z, :z) append_unit_if_needed!(plotattributes, :colorbar_title, u) @@ -69,7 +71,7 @@ const AMat{T} = AbstractArray{T,2} where T end # Recipe for vectors of vectors -@recipe function f(::Type{T}, x::T) where T <: AbstractVector{<:AbstractVector{<:Union{Missing,<:Quantity}}} +@recipe function f(::Type{T}, x::T) where T <: AbstractVector{<:AbstractVector{<:Union{Missing,<:Quantity, <:LogScaled}}} axisletter = plotattributes[:letter] # x, y, or z [fixaxis!(plotattributes, x, axisletter) for x in x] end @@ -81,19 +83,19 @@ end end # Recipes for functions -@recipe function f(f::Function, x::T) where T <: AVec{<:Union{Missing,<:Quantity}} +@recipe function f(f::Function, x::T) where T <: AVec{<:Union{Missing,<:Quantity, <:LogScaled}} x, f.(x) end -@recipe function f(x::T, f::Function) where T <: AVec{<:Union{Missing,<:Quantity}} +@recipe function f(x::T, f::Function) where T <: AVec{<:Union{Missing,<:Quantity, <:LogScaled}} x, f.(x) end -@recipe function f(x::T, y::AVec, f::Function) where T <: AVec{<:Union{Missing,<:Quantity}} +@recipe function f(x::T, y::AVec, f::Function) where T <: AVec{<:Union{Missing,<:Quantity, <:LogScaled}} x, y, f.(x',y) end -@recipe function f(x::AVec, y::T, f::Function) where T <: AVec{<:Union{Missing,<:Quantity}} +@recipe function f(x::AVec, y::T, f::Function) where T <: AVec{<:Union{Missing,<:Quantity, <:LogScaled}} x, y, f.(x',y) end -@recipe function f(x::T1, y::T2, f::Function) where {T1<:AVec{<:Union{Missing,<:Quantity}}, T2<:AVec{<:Union{Missing,<:Quantity}}} +@recipe function f(x::T1, y::T2, f::Function) where {T1<:AVec{<:Union{Missing,<:Quantity, <:LogScaled}}, T2<:AVec{<:Union{Missing,<:Quantity, <:LogScaled}}} x, y, f.(x',y) end @recipe function f(f::Function, u::Units) @@ -138,8 +140,8 @@ fixlinecolor!(attr) = ustripattribute!(attr, :line_z) function ustripattribute!(attr, key) if haskey(attr, key) v = attr[key] - u = unit(eltype(v)) - attr[key] = ustrip.(u, v) + u = _unit(eltype(v)) + attr[key] = _ustrip.(u, v) return u else return Unitful.NoUnits @@ -150,7 +152,7 @@ function ustripattribute!(attr, key, u) if haskey(attr, key) v = attr[key] if eltype(v) <: Quantity - attr[key] = ustrip.(u, v) + attr[key] = _ustrip.(u, v) end end u @@ -198,7 +200,7 @@ end Append unit to labels when appropriate =====================================# -function append_unit_if_needed!(attr, key, u::Unitful.Units) +function append_unit_if_needed!(attr, key, u::Union{Unitful.Units, Unitful.MixedUnits}) label = get(attr, key, nothing) append_unit_if_needed!(attr, key, label, u) end @@ -242,4 +244,30 @@ const UNIT_FORMATS = Dict( format_unit_label(l, u, f::Symbol) = format_unit_label(l,u,UNIT_FORMATS[f]) +#===================================== +Placeholder functions for consistent +=====================================# + +function _ustrip(u, x) + if eltype(x) <: Level + ustrip(uconvert(u, x)) + elseif eltype(x) <: Gain + getfield(uconvert(u, x), :val) + elseif u isa MixedUnits + x = uconvert(u, x) # convert Quantity -> LogScaled + if eltype(x) <: Level + ustrip(uconvert(u, x)) + elseif eltype(x) <: Gain + getfield(uconvert(u, x), :val) + end + else + ustrip(u, x) + end +end + +function _unit(x) + t = eltype(x) + u = t <: LogScaled ? logunit(t) : unit(t) +end + end # module diff --git a/test/runtests.jl b/test/runtests.jl index 8ee0af0..c91cd3b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -299,3 +299,30 @@ end plot!(plt, (1:3)m) @test yguide(plt) == "m" end + +@testset "LogScaled plots" begin + x, y, dbv, v = randn(3)*u"dBm", randn(3)*u"dB", rand(3)*u"dBV", rand(3)*u"V" + + @testset "no keyword argument" begin + @test xguide(plot(x,y)) == "dBm" + @test xseries(plot(x,y)) ≈ ustrip.(x) + @test yguide(plot(x,y)) == "dB" + @test yseries(plot(x,y)) ≈ ustrip.(y) + plot(x, dbv) + @test yseries(plot!(x, v)) ≈ ustrip(uconvert.(u"dBV", v)) + plot(x, v) + @test yseries(plot!(x, dbv)) ≈ ustrip(uconvert.(u"V", dbv)) + end + + @testset "labels" begin + @test xguide(plot(x, y, xlabel= "hello")) == "hello (dBm)" + @test xguide(plot(x, y, xlabel=P"hello")) == "hello" + @test yguide(plot(x, y, ylabel= "hello")) == "hello (dB)" + @test yguide(plot(x, y, ylabel=P"hello")) == "hello" + @test xguide(plot(x, y, xlabel= "hello", ylabel= "hello")) == "hello (dBm)" + @test xguide(plot(x, y, xlabel=P"hello", ylabel=P"hello")) == "hello" + @test yguide(plot(x, y, xlabel= "hello", ylabel= "hello")) == "hello (dB)" + @test yguide(plot(x, y, xlabel=P"hello", ylabel=P"hello")) == "hello" + end + +end \ No newline at end of file