Skip to content

Commit

Permalink
start Makie.jl plot recipes
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaqz committed Aug 30, 2023
1 parent 6af9c1e commit c9cefa9
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/DimensionalData.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Adapt,
Extents,
InvertedIndices,
IteratorInterfaceExtensions,
MakieCore,
RecipesBase,
PrecompileTools,
TableTraits,
Expand Down
87 changes: 87 additions & 0 deletions src/plotrecipes.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## Plots.jl recipes

abstract type DimPlotMode end
struct HeatMapLike <: DimPlotMode seriestype::Symbol end
struct WireframeLike <: DimPlotMode seriestype::Symbol end
Expand Down Expand Up @@ -128,6 +130,61 @@ end
throw(ArgumentError("$(x.seriestype) not implemented in $N dimensions"))
end

### Makie.jl recipes

# First, define default plot types for DimArrays
MakieCore.plottype(A::AbstractDimArray{<:Union{Missing,Number},1}) = MakieCore.Scatter
MakieCore.plottype(A::AbstractDimArray{<:Union{Missing,Number},2}) = MakieCore.Heatmap
# 3d A are a little more complicated - if dim3 is a singleton, then heatmap, otherwise volume
function MakieCore.plottype(A::AbstractDimArray{<:Union{Missing,Number},3})
if size(A, 3) == 1
MakieCore.Heatmap
else
MakieCore.Volume
end
end

# then, define how they are to be converted to plottable data
function MakieCore.convert_arguments(PB::MakieCore.PointBased, A::AbstractDimArray{<:Union{Number,Missing},1})
A = _prepare_makie(A)
return MakieCore.convert_arguments(PB, map(index, dims(A))..., parent(A))
end
# allow 3d A to be plotted as volumes
function MakieCore.convert_arguments(
::MakieCore.VolumeLike, A::AbstractDimArray{<:Union{Real,Missing},3}
)
A = _prepare_makie(A)
xs, ys, zs = lookup(A)
return (xs, ys, zs, parent(A))
end
# allow plotting 3d A with singleton third dimension (basically 2d A)
function MakieCore.convert_arguments(
::MakieCore.SurfaceLike, A::AbstractDimArray{<:Union{Missing,Number},2}
)
A = _prepare_makie(A)
xs, ys = lookup(A)
return (xs, ys, parent(A))
end
function MakieCore.convert_arguments(
::MakieCore.PointBased, A::AbstractDimArray{<:Union{Missing,Number},1}
)
A = _prepare_makie(A)
xs = lookup(A, 1)
return parent(xs), parent(A)
end
function MakieCore.convert_arguments(
::MakieCore.DiscreteSurface, A::AbstractDimArray{<:Union{Missing,Number},2}
)
A = _prepare_makie(A)
xs, ys = map(_lookup_edges, lookup(A))
return (xs, ys, parent(A))
end
# fallbacks with descriptive error messages
MakieCore.convert_arguments(t::MakieCore.ConversionTrait, r::AbstractDimArray) =
_makie_not_implemented_error(t, r)

### Shared utils

_fwdorderdims(x) = dims(dims(x), (TimeDim, XDim, IndependentDim, YDim, ZDim, DependentDim, DependentDim, Dimension, Dimension, Dimension))
_revorderdims(x) = reverse(_fwdorderdims(reverse(dims(x))))

Expand Down Expand Up @@ -185,3 +242,33 @@ function refdims_title(lookup::LookupArray, refdim::Dimension; kw...)
end
end


function _lookup_edges(l::LookupArray)
l = if l isa AbstractSampled
set(l, Intervals())
else
set(l, Sampled(; sampling=Intervals()))
end
if l == 1
return [bounds(l)...]
else
ib = intervalbounds(l)
if order(l) isa ForwardOrdered
edges = first.(ib)
push!(edges, last(last(ib)))
else
edges = last.(ib)
push!(edges, first(last(ib)))
end
return edges
end
end

_prepare_makie(A) = _missing_or_float32.(A) |> _permute_fwd |> _reorder

_missing_or_float32(num::Number) = Float32(num)
_missing_or_float32(::Missing) = missing

_reorder(A) = reorder(A, DD.ForwardOrdered)
_permute_fwd(A) = permutedims(A, _fwdorderdims(A))
_permute_rev(A) = permutedims(A, _revorderdims(A))

0 comments on commit c9cefa9

Please sign in to comment.