Dimensions
Dimensions are kept in the sub-module Dimensions
.
Dimensions
Sub-module for Dimension
s wrappers, and operations on them used in DimensionalData.jl.
To load Dimensions
types and methods into scope:
using DimensionalData
using DimensionalData.Dimensions
Dimensions have a type-hierarchy that organises plotting and dimension matching.
Dimension
Abstract supertype of all dimension types.
Example concrete implementations are X
, Y
, Z
, Ti
(Time), and the custom Dim
dimension.
Dimension
s label the axes of an AbstractDimArray
, or other dimensional objects, and are used to index into an array.
They may also wrap lookup values for each array axis. This may be any AbstractVector
matching the array axis length, but will usually be converted to a Lookup
when use in a constructed object.
A Lookup
gives more details about the dimension, such as that it is Categorical
or Sampled
as Points
or Intervals
along some transect. DimensionalData will attempt to guess the lookup from the passed-in index value.
Example:
using DimensionalData, Dates
x = X(2:2:10)
y = Y(['a', 'b', 'c'])
ti = Ti(DateTime(2021, 1):Month(1):DateTime(2021, 12))
A = DimArray(zeros(3, 5, 12), (y, x, ti))
# output
╭────────────────────────────╮
│ 3×5×12 DimArray{Float64,3} │
├────────────────────────────┴─────────────────────────────────────────── dims ┐
↓ Y Categorical{Char} ['a', 'b', 'c'] ForwardOrdered,
→ X Sampled{Int64} 2:2:10 ForwardOrdered Regular Points,
↗ Ti Sampled{Dates.DateTime} Dates.DateTime("2021-01-01T00:00:00"):Dates.Month(1):Dates.DateTime("2021-12-01T00:00:00") ForwardOrdered Regular Points
└──────────────────────────────────────────────────────────────────────────────┘
[:, :, 1]
↓ → 2 4 6 8 10
'a' 0.0 0.0 0.0 0.0 0.0
'b' 0.0 0.0 0.0 0.0 0.0
'c' 0.0 0.0 0.0 0.0 0.0
For simplicity, the same Dimension
types are also used as wrappers in getindex
, like:
x = A[X(2), Y(3)]
# output
╭────────────────────────────────╮
│ 12-element DimArray{Float64,1} │
├────────────────────────────────┴─────────────────────────────────────── dims ┐
↓ Ti Sampled{Dates.DateTime} Dates.DateTime("2021-01-01T00:00:00"):Dates.Month(1):Dates.DateTime("2021-12-01T00:00:00") ForwardOrdered Regular Points
└──────────────────────────────────────────────────────────────────────────────┘
2021-01-01T00:00:00 0.0
2021-02-01T00:00:00 0.0
2021-03-01T00:00:00 0.0
2021-04-01T00:00:00 0.0
2021-05-01T00:00:00 0.0
2021-06-01T00:00:00 0.0
2021-07-01T00:00:00 0.0
2021-08-01T00:00:00 0.0
2021-09-01T00:00:00 0.0
2021-10-01T00:00:00 0.0
2021-11-01T00:00:00 0.0
2021-12-01T00:00:00 0.0
A Dimension
can also wrap Selector
.
x = A[X(Between(3, 4)), Y(At('b'))]
# output
╭──────────────────────────╮
│ 1×12 DimArray{Float64,2} │
├──────────────────────────┴───────────────────────────────────────────── dims ┐
↓ X Sampled{Int64} 4:2:4 ForwardOrdered Regular Points,
→ Ti Sampled{Dates.DateTime} Dates.DateTime("2021-01-01T00:00:00"):Dates.Month(1):Dates.DateTime("2021-12-01T00:00:00") ForwardOrdered Regular Points
└──────────────────────────────────────────────────────────────────────────────┘
↓ → 2021-01-01T00:00:00 2021-02-01T00:00:00 … 2021-12-01T00:00:00
4 0.0 0.0 0.0
DependentDim <: Dimension
Abstract supertype for dependent dimensions. These will plot on the Y axis.
IndependentDim <: Dimension
Abstract supertype for independent dimensions. These will plot on the X axis.
XDim <: IndependentDim
Abstract supertype for all X dimensions.
YDim <: DependentDim
Abstract supertype for all Y dimensions.
ZDim <: DependentDim
Abstract supertype for all Z dimensions.
TimeDim <: IndependentDim
Abstract supertype for all time dimensions.
In a TimeDime
with Interval
sampling the locus will automatically be set to Start()
. Dates and times generally refer to the start of a month, hour, second etc., not the central point as is more common with spatial data. `
X <: XDim
X(val=:)
X Dimension
. X <: XDim <: IndependentDim
Examples
xdim = X(2:2:10)
val = A[X(1)]
mean(A; dims=X)
Y <: YDim
Y(val=:)
Y Dimension
. Y <: YDim <: DependentDim
Examples
ydim = Y(['a', 'b', 'c'])
val = A[Y(1)]
mean(A; dims=Y)
Z <: ZDim
Z(val=:)
Z Dimension
. Z <: ZDim <: Dimension
Example:
zdim = Z(10:10:100)
val = A[Z(1)]
mean(A; dims=Z)
m Ti <: TimeDim
Ti(val=:)
Time Dimension
. Ti <: TimeDim <: IndependentDim
Time
is already used by Dates, and T
is a common type parameter, We use Ti
to avoid clashes.
Example:
timedim = Ti(DateTime(2021, 1):Month(1):DateTime(2021, 12))
val = A[Ti(1)]
mean(A; dims=Ti)
Dim{S}(val=:)
A generic dimension. For use when custom dims are required when loading data from a file. Can be used as keyword arguments for indexing.
Dimension types take precedence over same named Dim
types when indexing with symbols, or e.g. creating Tables.jl keys.
julia> dim = Dim{:custom}(['a', 'b', 'c'])
custom ['a', 'b', 'c']
AnonDim <: Dimension
AnonDim()
Anonymous dimension. Used when extra dimensions are created, such as during transpose of a vector.
@dim typ [supertype=Dimension] [label::String=string(typ)]
Macro to easily define new dimensions.
The supertype will be inserted into the type of the dim. The default is simply YourDim <: Dimension
.
Making a Dimension inherit from XDim
, YDim
, ZDim
or TimeDim
will affect automatic plot layout and other methods that dispatch on these types. <: YDim
are plotted on the Y axis, <: XDim
on the X axis, etc.
label
is used in plots and similar, if the dimension is short for a longer word.
Example:
using DimensionalData
using DimensionalData: @dim, YDim, XDim
@dim Lat YDim "Latitude"
@dim Lon XDim "Longitude"
# output
Exported methods
These are widely useful methods for working with dimensions.
dims(x, [dims::Tuple]) => Tuple{Vararg{Dimension}}
dims(x, dim) => Dimension
Return a tuple of Dimension
s for an object, in the order that matches the axes or columns of the underlying data.
dims
can be Dimension
, Dimension
types, or Symbols
for Dim{Symbol}
.
The default is to return nothing
.
dims(x, query) => Tuple{Vararg{Dimension}}
dims(x, query...) => Tuple{Vararg{Dimension}}
Get the dimension(s) matching the type(s) of the query dimension.
Lookup can be an Int or an Dimension, or a tuple containing any combination of either.
Arguments
x
: any object with adims
method, or aTuple
ofDimension
.query
: Tuple or a singleDimension
orDimension
Type
.
Example
julia> using DimensionalData
julia> A = DimArray(ones(2, 3, 2), (X, Y, Z))
╭───────────────────────────╮
│ 2×3×2 DimArray{Float64,3} │
├───────────────────── dims ┤
↓ X, → Y, ↗ Z
└───────────────────────────┘
[:, :, 1]
1.0 1.0 1.0
1.0 1.0 1.0
julia> dims(A, (X, Y))
↓ X, → Y
otherdims(x, query) => Tuple{Vararg{Dimension,N}}
Get the dimensions of an object not in query
.
Arguments
x
: any object with adims
method, aTuple
ofDimension
.query
: Tuple or singleDimension
or dimensionType
.f
:<:
by default, but can be>:
to match abstract types to concrete types.
A tuple holding the unmatched dimensions is always returned.
Example
julia> using DimensionalData, DimensionalData.Dimensions
julia> A = DimArray(ones(10, 10, 10), (X, Y, Z));
julia> otherdims(A, X)
↓ Y, → Z
julia> otherdims(A, (Y, Z))
↓ X
dimnum(x, query::Tuple) => NTuple{Int}
dimnum(x, query) => Int
Get the number(s) of Dimension
(s) as ordered in the dimensions of an object.
Arguments
x
: any object with adims
method, aTuple
ofDimension
or a singleDimension
.query
: Tuple, Array or singleDimension
or dimensionType
.
The return type will be a Tuple of Int
or a single Int
, depending on whether query
is a Tuple
or single Dimension
.
Example
julia> using DimensionalData
julia> A = DimArray(ones(10, 10, 10), (X, Y, Z));
julia> dimnum(A, (Z, X, Y))
(3, 1, 2)
julia> dimnum(A, Y)
2
hasdim([f], x, query::Tuple) => NTuple{Bool}
hasdim([f], x, query...) => NTuple{Bool}
hasdim([f], x, query) => Bool
Check if an object x
has dimensions that match or inherit from the query
dimensions.
Arguments
x
: any object with adims
method, aTuple
ofDimension
or a singleDimension
.query
: Tuple or singleDimension
or dimensionType
.f
:<:
by default, but can be>:
to match abstract types to concrete types.
Check if an object or tuple contains an Dimension
, or a tuple of dimensions.
Example
julia> using DimensionalData
julia> A = DimArray(ones(10, 10, 10), (X, Y, Z));
julia> hasdim(A, X)
true
julia> hasdim(A, (Z, X, Y))
(true, true, true)
julia> hasdim(A, Ti)
false
Non-exported methods
lookup(x::Dimension) => Lookup
lookup(x, [dims::Tuple]) => Tuple{Vararg{Lookup}}
lookup(x::Tuple) => Tuple{Vararg{Lookup}}
lookup(x, dim) => Lookup
Returns the Lookup
of a dimension. This dictates properties of the dimension such as array axis and lookup order, and sampling properties.
dims
can be a Dimension
, a dimension type, or a tuple of either.
This is separate from val
in that it will only work when dimensions actually contain an AbstractArray
lookup, and can be used on a DimArray
or DimStack
to retrieve all lookups, as there is no ambiguity of meaning as there is with val
.
label(x) => String
label(x, dims::Tuple) => NTuple{N,String}
label(x, dim) => String
label(xs::Tuple) => NTuple{N,String}
Get a plot label for data or a dimension. This will include the name and units if they exist, and anything else that should be shown on a plot.
Second argument dims
can be Dimension
s, Dimension
types, or Symbols
for Dim{Symbol}
.
format(dims, x) => Tuple{Vararg{Dimension,N}}
Format the passed-in dimension(s) dims
to match the object x
.
Errors are thrown if dims don't match the array dims or size, and any fields holding Auto-
objects are filled with guessed objects.
If a Lookup
hasn't been specified, a lookup is chosen based on the type and element type of the values.
dims2indices(dim::Dimension, I) => NTuple{Union{Colon,AbstractArray,Int}}
Convert a Dimension
or Selector
I
to indices of Int
, AbstractArray
or Colon
.
selectindices(lookups, selectors)
Converts Selector
to regular indices.
Primitive methods
These low-level methods are really for internal use, but can be useful for writing dimensional algorithms.
They are not guaranteed to keep their interface, but usually will.
commondims([f], x, query) => Tuple{Vararg{Dimension}}
This is basically dims(x, query)
where the order of the original is kept, unlike dims
where the query tuple determines the order
Also unlike dims
,commondims
always returns a Tuple
, no matter the input. No errors are thrown if dims are absent from either x
or query
.
f
is <:
by default, but can be >:
to sort abstract types by concrete types.
julia> using DimensionalData, .Dimensions
julia> A = DimArray(ones(10, 10, 10), (X, Y, Z));
julia> commondims(A, X)
↓ X
julia> commondims(A, (X, Z))
↓ X, → Z
julia> commondims(A, Ti)
()
name2dim(s::Symbol) => Dimension
name2dim(dims...) => Tuple{Dimension,Vararg}
name2dim(dims::Tuple) => Tuple{Dimension,Vararg}
Convert a symbol to a dimension object. :X
, :Y
, :Ti
etc will be converted to X()
, Y()
, Ti()
, as with any other dims generated with the @dim
macro.
All other Symbol
s S
will generate Dim{S}()
dimensions.
reducedims(x, dimstoreduce) => Tuple{Vararg{Dimension}}
Replace the specified dimensions with an index of length 1. This is usually to match a new array size where an axis has been reduced with a method like mean
or reduce
to a length of 1, but the number of dimensions has not changed.
Lookup
traits are also updated to correspond to the change in cell step, sampling type and order.
swapdims(x::T, newdims) => T
swapdims(dims::Tuple, newdims) => Tuple{Vararg{Dimension}}
Swap dimensions for the passed in dimensions, in the order passed.
Passing in the Dimension
types rewraps the dimension index, keeping the index values and metadata, while constructed Dimension
objects replace the original dimension. nothing
leaves the original dimension as-is.
Arguments
x
: any object with adims
method or aTuple
ofDimension
.newdim
: Tuple ofDimension
or dimensionType
.
Example
using DimensionalData
A = ones(X(2), Y(4), Z(2))
Dimensions.swapdims(A, (Dim{:a}, Dim{:b}, Dim{:c}))
# output
╭───────────────────────────╮
│ 2×4×2 DimArray{Float64,3} │
├───────────────────── dims ┤
↓ a, → b, ↗ c
└───────────────────────────┘
[:, :, 1]
1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0
slicedims(x, I) => Tuple{Tuple,Tuple}
slicedims(f, x, I) => Tuple{Tuple,Tuple}
Slice the dimensions to match the axis values of the new array.
All methods return a tuple containing two tuples: the new dimensions, and the reference dimensions. The ref dimensions are no longer used in the new struct but are useful to give context to plots.
Called at the array level the returned tuple will also include the previous reference dims attached to the array.
Arguments
f
: a functiongetindex
,view
ordotview
. This will be used for slicinggetindex
is the default iff
is not included.x
: AnAbstractDimArray
,Tuple
ofDimension
, orDimension
I
: A tuple ofInteger
,Colon
orAbstractArray
comparedims(A::AbstractDimArray...; kw...)
comparedims(A::Tuple...; kw...)
comparedims(A::Dimension...; kw...)
comparedims(::Type{Bool}, args...; kw...)
Check that dimensions or tuples of dimensions passed as each argument are the same, and return the first valid dimension. If AbstractDimArray
s are passed as arguments their dimensions are compared.
Empty tuples and nothing
dimension values are ignored, returning the Dimension
value if it exists.
Passing Bool
as the first argument means true
/false
will be returned, rather than throwing an error.
Keywords
These are all Bool
flags:
type
: compare dimension type,true
by default.valtype
: compare wrapped value type,false
by default.val
: compare wrapped values,false
by default.order
: compare order,false
by default.length
: compare lengths,true
by default.ignore_length_one
: ignore length1
in comparisons, and return whichever dimension is not length 1, if any. This is useful in e.g. broadcasting comparisons.false
by default.warn
: aString
ornothing
. Used only forBool
methods, to give a warning forfalse
values and includewarn
in the warning text.
combinedims(xs; check=true)
Combine the dimensions of each object in xs
, in the order they are found.
sortdims([f], tosort, order) => Tuple
Sort dimensions tosort
by order
. Dimensions in order
but missing from tosort
are replaced with nothing
.
tosort
and order
can be Tuple
s or Vector
s or Dimension or dimension type. Abstract supertypes like TimeDim
can be used in order
.
f
is <:
by default, but can be >:
to sort abstract types by concrete types.
basetypeof(x) => Type
Get the "base" type of an object - the minimum required to define the object without it's fields. By default this is the full UnionAll
for the type. But custom basetypeof
methods can be defined for types with free type parameters.
In DimensionalData this is primarily used for comparing Dimension
s, where Dim{:x}
is different from Dim{:y}
.
basedims(ds::Tuple)
basedims(d::Union{Dimension,Symbol,Type})
Returns basetypeof(d)()
or a Tuple
of called on a Tuple
.
See basetypeof
setdims(X, newdims) => AbstractArray
setdims(::Tuple, newdims) => Tuple{Vararg{Dimension,N}}
Replaces the first dim matching <: basetypeof(newdim)
with newdim, and returns a new object or tuple with the dimension updated.
Arguments
x
: any object with adims
method, aTuple
ofDimension
or a singleDimension
.newdim
: Tuple or singleDimension
,Type
orSymbol
.
Example
using DimensionalData, DimensionalData.Dimensions, DimensionalData.Lookups
A = ones(X(10), Y(10:10:100))
B = setdims(A, Y(Categorical('a':'j'; order=ForwardOrdered())))
lookup(B, Y)
# output
Categorical{Char} ForwardOrdered
wrapping: 'a':1:'j'
dimsmatch([f], dim, query) => Bool
dimsmatch([f], dims::Tuple, query::Tuple) => Bool
Compare 2 dimensions or Tuple
of Dimension
are of the same base type, or are at least rotations/transformations of the same type.
f
is <:
by default, but can be >:
to match abstract types to concrete types.