DimensionalData.jl
DimensionalData.jl copied to clipboard
StackOverflowError with Makie Extension and Unitful Dimensions
When I try to plot a DimArray with Unitful dimensions I am getting a StackOverflowError. There was previously a resolved issue about what seems to be the same error: https://github.com/rafaqz/DimensionalData.jl/issues/723. It seems that this issue was reintroduced with version 0.29.19.
Here is the same minimal example as provided by @david-macmahon in the original issue.
Version 0.29.18 works:
(jl_uAVeuD) pkg> st CairoMakie DimensionalData Unitful
Status `/tmp/jl_uAVeuD/Project.toml`
⌃ [13f3f980] CairoMakie v0.14.0
⌃ [0703355e] DimensionalData v0.29.18
[1986cc42] Unitful v1.24.0
Info Packages marked with ⌃ have new versions available and may be upgradable.
julia> using DimensionalData, CairoMakie, Unitful
julia> dd = DimArray(rand(3,5), (Dim{:freq}(1.0:0.5:2.0), Dim{:time}(0:4)))
┌ 3×5 DimArray{Float64, 2} ┐
├──────────────────────────┴──────────────────────────────────── dims ┐
↓ freq Sampled{Float64} 1.0:0.5:2.0 ForwardOrdered Regular Points,
→ time Sampled{Int64} 0:4 ForwardOrdered Regular Points
└─────────────────────────────────────────────────────────────────────┘
↓ → 0 1 2 3 4
1.0 0.866261 0.542912 0.556222 0.575055 0.423188
1.5 0.716689 0.267359 0.25917 0.267714 0.199823
2.0 0.619127 0.838477 0.821431 0.261603 0.0693282
julia> plot(dd) # works
julia> ddu = DimArray(rand(3,5), (Dim{:freq}((1.0:0.5:2.0)u"Hz"), Dim{:time}((0:4)u"s")))
┌ 3×5 DimArray{Float64, 2} ┐
├──────────────────────────┴────────────────────────────────────────────────────────── dims ┐
↓ freq Sampled{Quantity{Float64, 𝐓^-1, Unitful.FreeUnits{(Hz,), 𝐓^-1, nothing}}} (1.0:0.5:2.0) Hz ForwardOrdered Regular Points,
→ time Sampled{Quantity{Int64, 𝐓, Unitful.FreeUnits{(s,), 𝐓, nothing}}} (0:4) s ForwardOrdered Regular Points
└───────────────────────────────────────────────────────────────────────────────────────────┘
↓ → 0 s 1 s 2 s 3 s 4 s
1.0 Hz 0.205511 0.993605 0.966492 0.787188 0.685997
1.5 Hz 0.905903 0.272701 0.617019 0.161883 0.0868278
2.0 Hz 0.7243 0.735437 0.350271 0.906789 0.981961
julia> plot(ddu) # also works
Version 0.29.19 does not work:
(jl_Y1J9tn) pkg> st CairoMakie DimensionalData Unitful
Status `/tmp/jl_Y1J9tn/Project.toml`
[13f3f980] CairoMakie v0.15.6
⌃ [0703355e] DimensionalData v0.29.19
[1986cc42] Unitful v1.24.0
Info Packages marked with ⌃ have new versions available and may be upgradable.
julia> using DimensionalData, CairoMakie, Unitful
julia> dd = DimArray(rand(3,5), (Dim{:freq}(1.0:0.5:2.0), Dim{:time}(0:4)))
┌ 3×5 DimArray{Float64, 2} ┐
├──────────────────────────┴──────────────────────────────────── dims ┐
↓ freq Sampled{Float64} 1.0:0.5:2.0 ForwardOrdered Regular Points,
→ time Sampled{Int64} 0:4 ForwardOrdered Regular Points
└─────────────────────────────────────────────────────────────────────┘
↓ → 0 1 2 3 4
1.0 0.863165 0.0334873 0.951236 0.905314 0.579467
1.5 0.32396 0.988554 0.776589 0.912863 0.206955
2.0 0.0461706 0.880968 0.32979 0.0800129 0.662683
julia> plot(dd) # works
julia> ddu = DimArray(rand(3,5), (Dim{:freq}((1.0:0.5:2.0)u"Hz"), Dim{:time}((0:4)u"s")))
┌ 3×5 DimArray{Float64, 2} ┐
├──────────────────────────┴────────────────────────────────────────────────────────── dims ┐
↓ freq Sampled{Quantity{Float64, 𝐓^-1, Unitful.FreeUnits{(Hz,), 𝐓^-1, nothing}}} (1.0:0.5:2.0) Hz ForwardOrdered Regular Points,
→ time Sampled{Quantity{Int64, 𝐓, Unitful.FreeUnits{(s,), 𝐓, nothing}}} (0:4) s ForwardOrdered Regular Points
└───────────────────────────────────────────────────────────────────────────────────────────┘
↓ → 0 s 1 s 2 s 3 s 4 s
1.0 Hz 0.290704 0.777649 0.169968 0.104919 0.900903
1.5 Hz 0.00916393 0.763765 0.994425 0.47843 0.693603
2.0 Hz 0.917727 0.525552 0.0422042 0.418307 0.787847
julia> plot(ddu)
ERROR: StackOverflowError:
Stacktrace:
[1] Base.TwicePrecision{Float64}(nd::Tuple{Int128, Int128})
@ Base ./twiceprecision.jl:222
[2] steprangelen_hp(::Type{…}, ref::Tuple{…}, step::Tuple{…}, nb::Int64, len::Int64, offset::Int64)
@ Base ./twiceprecision.jl:344
[3] _linspace(::Type{Float64}, start_n::Int64, stop_n::Int64, len::Int64, den::Int64)
@ Base ./twiceprecision.jl:730
[4] range_start_stop_length(start::Float64, stop::Float64, len::Int64)
@ Base ./twiceprecision.jl:660
[5] _range
@ ./range.jl:167 [inlined]
[6] _range(start::Quantity{…}, ::Nothing, stop::Quantity{…}, len::Int64)
@ Unitful ~/.julia/packages/Unitful/sxiHA/src/range.jl:26
[7] range
@ ./range.jl:148 [inlined]
[8] to_linspace
@ ~/.julia/packages/Makie/4JW9B/src/conversions.jl:737 [inlined]
[9] convert_arguments(P::CellGrid, x::StepRangeLen{…}, y::StepRangeLen{…}, z::Matrix{…}) (repeats 79979 times)
@ Makie ~/.julia/packages/Makie/4JW9B/src/conversions.jl:372
Some type information was truncated. Use `show(err)` to see complete types.
Huh, I wonder if thats us or Makie
For what it is worth, one dimensional data works as expected.
julia> ddu1 = DimArray(rand(3), (Dim{:freq}((1.0:0.5:2.0)u"Hz"),))
Also when I use heatmap, I get a bit more stacktrace:
julia> heatmap(ddu)
(xlookup, ylookup) = ((1.0:0.5:2.0) Hz, (0:4) s)
ERROR: StackOverflowError:
Stacktrace:
[1] Base.TwicePrecision{Float64}(nd::Tuple{Int128, Int128})
@ Base ./twiceprecision.jl:222
[2] steprangelen_hp(::Type{…}, ref::Tuple{…}, step::Tuple{…}, nb::Int64, len::Int64, offset::Int64)
@ Base ./twiceprecision.jl:344
[3] _linspace(::Type{Float64}, start_n::Int64, stop_n::Int64, len::Int64, den::Int64)
@ Base ./twiceprecision.jl:730
[4] range_start_stop_length(start::Float64, stop::Float64, len::Int64)
@ Base ./twiceprecision.jl:660
[5] _range
@ ./range.jl:167 [inlined]
[6] _range(start::Quantity{…}, ::Nothing, stop::Quantity{…}, len::Int64)
@ Unitful ~/.julia/packages/Unitful/sxiHA/src/range.jl:26
[7] range
@ ./range.jl:148 [inlined]
[8] to_linspace
@ ~/.julia/packages/Makie/4JW9B/src/conversions.jl:737 [inlined]
[9] convert_arguments(P::CellGrid, x::StepRangeLen{…}, y::StepRangeLen{…}, z::Matrix{…}) (repeats 21637 times)
@ Makie ~/.julia/packages/Makie/4JW9B/src/conversions.jl:372
[10] convert_arguments(P::CellGrid, x::StepRangeLen{…}, y::StepRange{…}, z::Matrix{…})
@ Makie ~/.julia/packages/Makie/4JW9B/src/conversions.jl:372
[11] convert_arguments(::Type{…}, ::StepRangeLen{…}, ::Vararg{…}; kw::@Kwargs{})
@ Makie ~/.julia/packages/Makie/4JW9B/src/conversions.jl:26
[12] convert_arguments(::Type{…}, ::StepRangeLen{…}, ::StepRange{…}, ::Matrix{…})
@ Makie ~/.julia/packages/Makie/4JW9B/src/conversions.jl:14
[13] convert_arguments(P::Type{…}, A::DimMatrix{…}; xdim::Nothing, ydim::Nothing)
@ DimensionalDataMakie ~/.julia/dev/DimensionalData/ext/DimensionalDataMakie.jl:487
[14] convert_arguments
@ ~/.julia/dev/DimensionalData/ext/DimensionalDataMakie.jl:481 [inlined]
[15] #default_axis_type#78
@ ~/.julia/dev/DimensionalData/ext/DimensionalDataMakie.jl:370 [inlined]
[16] default_axis_type
@ ~/.julia/dev/DimensionalData/ext/DimensionalDataMakie.jl:369 [inlined]
[17] heatmap(fig::GridPosition, A::DimMatrix{…}; xdim::Nothing, ydim::Nothing, colorbar::@NamedTuple{}, axis::@NamedTuple{}, plot_attributes::@Kwargs{})
@ DimensionalDataMakie ~/.julia/dev/DimensionalData/ext/DimensionalDataMakie.jl:278
[18] heatmap
@ ~/.julia/dev/DimensionalData/ext/DimensionalDataMakie.jl:273 [inlined]
[19] #heatmap#11
@ ~/.julia/dev/DimensionalData/ext/DimensionalDataMakie.jl:79 [inlined]
[20] heatmap(A::DimMatrix{…})
@ DimensionalDataMakie ~/.julia/dev/DimensionalData/ext/DimensionalDataMakie.jl:77
[21] top-level scope
@ REPL[32]:1
Some type information was truncated. Use `show(err)` to see complete types.
It seems to be Makie, but I am still a bit confused, why this wasn't hit on 0.29.18.
julia> xlookup = (1.0:0.5:2.0)u"Hz"
(1.0:0.5:2.0) Hz
julia> Makie.convert_arguments(CellGrid(), xlookup, 0:4, rand(3,5))
ERROR: StackOverflowError:
Stacktrace:
[1] Base.TwicePrecision{Float64}(nd::Tuple{Int128, Int128})
@ Base ./twiceprecision.jl:222
[2] steprangelen_hp(::Type{Float64}, ref::Tuple{Int128, Int128}, step::Tuple{Int128, Int128}, nb::Int64, len::Int64, offset::Int64)
@ Base ./twiceprecision.jl:344
[3] _linspace(::Type{Float64}, start_n::Int64, stop_n::Int64, len::Int64, den::Int64)
@ Base ./twiceprecision.jl:730
[4] range_start_stop_length(start::Float64, stop::Float64, len::Int64)
@ Base ./twiceprecision.jl:660
[5] _range
@ ./range.jl:167 [inlined]
[6] _range(start::Quantity{Float64, 𝐓^-1, Unitful.FreeUnits{(Hz,), 𝐓^-1, nothing}}, ::Nothing, stop::Quantity{Float64, 𝐓^-1, Unitful.FreeUnits{(Hz,), 𝐓^-1, nothing}}, len::Int64)
@ Unitful ~/.julia/packages/Unitful/sxiHA/src/range.jl:26
[7] range
@ ./range.jl:148 [inlined]
[8] to_linspace
@ ~/.julia/packages/Makie/4JW9B/src/conversions.jl:737 [inlined]
[9] convert_arguments(P::CellGrid, x::StepRangeLen{Quantity{…}, Base.TwicePrecision{…}, Base.TwicePrecision{…}, Int64}, y::StepRangeLen{Float64, Base.TwicePrecision{…}, Base.TwicePrecision{…}, Int64}, z::Matrix{Float64}) (repeats 47543 times)
@ Makie ~/.julia/packages/Makie/4JW9B/src/conversions.jl:372
[10] convert_arguments(P::CellGrid, x::StepRangeLen{Quantity{Float64, 𝐓^-1, Unitful.FreeUnits{…}}, Base.TwicePrecision{Quantity{…}}, Base.TwicePrecision{Quantity{…}}, Int64}, y::UnitRange{Int64}, z::Matrix{Float64})
@ Makie ~/.julia/packages/Makie/4JW9B/src/conversions.jl:372
[11] top-level scope
@ REPL[19]:1
Some type information was truncated. Use `show(err)` to see complete types.
Maybe @DylanMMarques you have some ideas, because you worked on the DimensionalData change that landed in 0.29.19.
Yeah, looks like Makie to me. Ping @simondanisch in case you know what might be going on
It seems it worked fine on 0.29.18 because the output of convert_arguments was defined as:
return xs, ys, last(Makie.convert_arguments(P, z))
while for 0.29.19, it is defined as:
return Makie.convert_arguments(P, xs, ys, z)
I tested this as:
struct MyType1
end
Makie.convert_arguments(P::Type{Heatmap}, x::MyType1)= Makie.convert_arguments(P, (1:6)u"s", (1:11), rand(5,10))
heatmap(MyType1()) # stack overflow error
struct MyType2
end
Makie.convert_arguments(P::Type{Heatmap}, x::MyType2)= (1:6)u"s", (1:11), last(Makie.convert_arguments(P, rand(5,10)))
heatmap(MyType2()) # works fine
A work around could be to defined similarly as in 0.29.18. I don't think that it will create new problems, but I haven't tested it.