Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 42 additions & 36 deletions src/UnitfulRecipes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module UnitfulRecipes

using RecipesBase
using Unitful: Quantity, unit, ustrip, Unitful, dimension, Units
using Infiltrator
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only for development purposes

export @P_str

const clims_types = (:contour, :contourf, :heatmap, :surface)
Expand All @@ -12,11 +13,12 @@ Main recipe

@recipe function f(::Type{T}, x::T) where T <: AbstractArray{<:Union{Missing,<:Quantity}}
axisletter = plotattributes[:letter] # x, y, or z
if (axisletter == :z) &&
get(plotattributes, :seriestype, :nothing) ∈ clims_types
u = get(plotattributes, :zunit, unit(eltype(x)))
ustripattribute!(plotattributes, :clims, u)
append_unit_if_needed!(plotattributes, :colorbar_title, u)
if (axisletter == :z) && get(plotattributes, :seriestype, :nothing) ∈ clims_types
# I don't know why fill_z gets turned into a Vector, it needs to be reshaped back
plotattributes[:fill_z] = reshape(
get(plotattributes, :fill_z, x),
size(x)...
)
end
fixaxis!(plotattributes, x, axisletter)
end
Expand All @@ -27,42 +29,41 @@ function fixaxis!(attr, x, axisletter)
axislims = Symbol(axisletter, :lims) # xlims, ylims, zlims
axisticks = Symbol(axisletter, :ticks) # xticks, yticks, zticks
err = Symbol(axisletter, :error) # xerror, yerror, zerror
axisunit = Symbol(axisletter, :unit) # xunit, yunit, zunit
axis = Symbol(axisletter, :axis) # xaxis, yaxis, zaxis
# Get the unit
u = pop!(attr, axisunit, unit(eltype(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
label = attr[:plot_object][sp][axis][:guide]
if label isa UnitfulString
u = label.unit
end
# If label was not given as an argument, reuse
get!(attr, axislabel, label)
end

u = fixlabel!(attr, axisletter, unit(first(x)))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much of this code needed to be repeated for the c axis, so I factored it out.

# Fix the attributes: labels, lims, ticks, marker/line stuff, etc.
append_unit_if_needed!(attr, axislabel, u)
ustripattribute!(attr, axislims, u)
ustripattribute!(attr, axisticks, u)
ustripattribute!(attr, err, u)
fixmarkercolor!(attr)
fixcolors!(attr)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to run a single pass over all three color arguments, to combine into one axis.

fixmarkersize!(attr)
fixlinecolor!(attr)
# Strip the unit
ustrip.(u, x)
return 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)))
ustripattribute!(plotattributes, :clims, u)
z = fixaxis!(plotattributes, z, :z)
append_unit_if_needed!(plotattributes, :colorbar_title, u)
x, y, z
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this recipe if x, y and z are correctly identified as type targets for themselves.

function fixlabel!(attr, axisletter, dataunit)
u = pop!(attr, Symbol(axisletter,:unit), dataunit)
sp = get(attr, :subplot, 1)
if axisletter == :c
labelname = :colorbar_title
axisname = nothing
else
labelname = :guide
axisname = Symbol(axisletter, :axis)
end
if sp ≤ length(attr[:plot_object]) && attr[:plot_object].n > 0
label = getlabel(attr, sp, axisname, labelname)
if label isa UnitfulString
u = label.unit
end
get!(attr, labelname, label)
end
return u
end
getlabel(attr, sp, axisname, labelname) = attr[:plot_object][sp][axisname][labelname]
getlabel(attr, sp, axisname::Nothing, labelname) = attr[:plot_object][sp][labelname]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a limitation in Plots that it's attr[:plot_object][sp][:colorbar_title] rather than attr[:plot_object][sp][:caxis][:guide], but it is what it is.



# Recipe for vectors of vectors
@recipe function f(::Type{T}, x::T) where T <: AbstractVector{<:AbstractVector{<:Union{Missing,<:Quantity}}}
Expand All @@ -76,6 +77,9 @@ end
Float64[]*x
end

const AVec = AbstractVector
const AMat{T} = AbstractArray{T,2} where T

# Recipes for functions
@recipe function f(f::Function, x::T) where T <: AVec{<:Union{Missing,<:Quantity}}
x, f.(x)
Expand Down Expand Up @@ -122,13 +126,15 @@ Attribute fixing
===============#

# Markers / lines
function fixmarkercolor!(attr)
u = ustripattribute!(attr, :marker_z)
ustripattribute!(attr, :clims, u)
u == Unitful.NoUnits || append_unit_if_needed!(attr, :colorbar_title, u)
function fixcolors!(attr)
u = unit(first(get(attr, :line_z, get(attr, :marker_z, get(attr, :fill_z, [1])))))
u = fixlabel!(attr, :c, u)
for key in [:line_z, :marker_z, :fill_z, :clims]
ustripattribute!(attr, key, u)
end
append_unit_if_needed!(attr, :colorbar_title, u)
end
fixmarkersize!(attr) = ustripattribute!(attr, :markersize)
fixlinecolor!(attr) = ustripattribute!(attr, :line_z)

# strip unit from attribute[key]
function ustripattribute!(attr, key)
Expand Down