ITADN

plot! fails for time-based DimArrays

#1160Openthirtysixbananas 创建于 2026-01-03
Works: ``` y1 = DimArray(rand(Float64, 11), (times=1:11,),) y2 = DimArray(rand(Float64, 11), (times=1:11,),) f = Figure() ax = Axis(f[1,1]) plot!(ax, y1) # Scatter{Tuple{Vector{Point{2, Float64}}}} plot!(ax, y2) # Scatter{Tuple{Vector{Point{2, Float64}}}} ``` Doesn't work: ``` y1 = DimArray( rand(Float64, 11), (times=DateTime("2026-01-01"):Minute(1):DateTime("2026-01-01T00:10:00"),), ) y2 = DimArray( rand(Float64, 11), (times=DateTime("2026-01-01"):Minute(1):DateTime("2026-01-01T00:10:00"),), ) f = Figure() ax = Axis(f[1,1]) plot!(ax, y1) # Scatter{Tuple{Vector{Point{2, Float64}}}} plot!(ax, y2) # ERROR: ArgumentError: Conversion failed for Scatter (With conversion trait PointBased()) with args: Tuple{DimVector{Float64, Tuple{Dim{:times, DimensionalData.Dimensions.Lookups.Sampled{DateTime, StepRange{DateTime, Minute}, DimensionalData.Dimensions.Lookups.ForwardOrdered, DimensionalData.Dimensions.Lookups.Regular{Minute}, DimensionalData.Dimensions.Lookups.Points, DimensionalData.Dimensions.Lookups.NoMetadata}}}, Tuple{}, Vector{Float64}, DimensionalData.NoName, DimensionalData.Dimensions.Lookups.NoMetadata}} Got converted to: Tuple{StepRange{DateTime, Minute}, Vector{Float64}} Scatter requires to convert to argument types Tuple{AbstractVector{<:Union{Point2, Point3}}}, which convert_arguments didn't succeed in. To fix this overload convert_arguments(P, args...) for Scatter or PointBased() and return an object of type Tuple{AbstractVector{<:Union{Point2, Point3}}}.` Stacktrace: [1] argument_error(PTrait::PointBased, P::Type, args::Tuple{…}, user_kw::Dict{…}, converted::Tuple{…}) @ Makie ~/.julia/packages/Makie/Vn16E/src/compute-plots.jl:725 [2] (Scatter)(user_args::Tuple{DimVector{…}}, user_attributes::Dict{Symbol, Any}) @ Makie ~/.julia/packages/Makie/Vn16E/src/compute-plots.jl:773 [3] _create_plot!(::Function, ::Dict{…}, ::Axis, ::DimVector{…}) @ Makie ~/.julia/packages/Makie/Vn16E/src/figureplotting.jl:403 [4] #scatter!#62 @ ~/.julia/packages/Makie/Vn16E/src/recipes.jl:534 [inlined] [5] scatter! @ ~/.julia/packages/Makie/Vn16E/src/recipes.jl:532 [inlined] [6] plot!(ax::Axis, dd::DimVector{…}) @ DimensionalDataMakieExt ~/.julia/packages/DimensionalData/FWnw9/ext/DimensionalDataMakieExt.jl:395 ``` As a sanity check I tried plotting with DateTime on the x-axis and it works, so the above problem is specific to DD, not Makie: ``` ts = DateTime("2026-01-01"):Minute(1):DateTime("2026-01-01T00:10:00") y1 = rand(Float64, 11) y2 = rand(Float64, 11) f = Figure() ax = Axis(f[1,1]) plot!(ax, ts, y1) # Scatter{Tuple{Vector{Point{2, Float64}}}} plot!(ax, ts, y2) # Scatter{Tuple{Vector{Point{2, Float64}}}} ``` EDIT: Calls [here](https://github.com/rafaqz/DimensionalData.jl/blob/2043ccc682481ef5f7295fd78b714a3a188643d8/ext/DimensionalDataMakieExt.jl#L395) so this is a simpler path to reproduce: ``` Makie.scatter!(ax, y1) ``` Does this check before throwing: https://github.com/MakieOrg/Makie.jl/blob/4a6728146ca4d5b3d20ee9244300788243697c79/Makie/src/compute-plots.jl#L780 In both cases, `PTrait = PointBased(), P=Scatter`. However, in the first plot! ``` converted=(Point{2, Float64}[[6.39029088e13, 0.5836928495029402], [6.390290886e13, 0.384911441829076], [6.390290892e13, 0.1530611230665475], [6.390290898e13, 0.416598093899766], [6.390290904e13, 0.1913697055696404], [6.39029091e13, 0.07931893959562897], [6.390290916e13, 0.5810192663574537], [6.390290922e13, 0.4698605070411458], [6.390290928e13, 0.2241905689270648], [6.390290934e13, 0.25124129374053417], [6.39029094e13, 0.9313477533438733]],) got_converted(P, PTrait, converted) # true and succeeds ``` but in the second ``` converted=(DateTime("2026-01-01T00:00:00"):Minute(1):DateTime("2026-01-01T00:10:00"), [0.646820062789859, 0.5319466876655881, 0.36043739283964304, 0.8572681488599282, 0.4556710116927154, 0.6731147331017542, 0.08469344244360877, 0.4920890801070882, 0.9769361150754856, 0.9531765290732815, 0.3459698165949199]) got_converted(P, PTrait, converted) # false and throws ``` ``` PTrait = Makie.PointBased() P = Makie.Scatter converted1=(Point{2, Float64}[[6.39029088e13, 0.5836928495029402], [6.390290886e13, 0.384911441829076], [6.390290892e13, 0.1530611230665475], [6.390290898e13, 0.416598093899766], [6.390290904e13, 0.1913697055696404], [6.39029091e13, 0.07931893959562897], [6.390290916e13, 0.5810192663574537], [6.390290922e13, 0.4698605070411458], [6.390290928e13, 0.2241905689270648], [6.390290934e13, 0.25124129374053417], [6.39029094e13, 0.9313477533438733]],) converted2=(DateTime("2026-01-01T00:00:00"):Minute(1):DateTime("2026-01-01T00:10:00"), [0.646820062789859, 0.5319466876655881, 0.36043739283964304, 0.8572681488599282, 0.4556710116927154, 0.6731147331017542, 0.08469344244360877, 0.4920890801070882, 0.9769361150754856, 0.9531765290732815, 0.3459698165949199]) Makie.got_converted(P, PTrait, converted1) # true Makie.got_converted(P, PTrait, converted2) # false ``` EDIT2: On entering this function https://github.com/MakieOrg/Makie.jl/blob/4a6728146ca4d5b3d20ee9244300788243697c79/Makie/src/compute-plots.jl#L746 in boths cases, `user_args: ([0.646820062789859, 0.5319466876655881, 0.36043739283964304, 0.8572681488599282, 0.4556710116927154, 0.6731147331017542, 0.08469344244360877, 0.4920890801070882, 0.9769361150754856, 0.9531765290732815, 0.3459698165949199],)` However user_attributes in the first case is ``` Dict{Symbol, Any}( :dim_conversions => Makie.DimConversions( ( Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing), Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing), Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing), ), ), ) ``` whereas in the second case its ``` Dict{Symbol, Any}( :dim_conversions => Makie.DimConversions( ( Observable{Union{Nothing, Makie.AbstractDimConversion}}(Makie.DateTimeConversion(Observable(DateTime))), Observable{Union{Nothing, Makie.AbstractDimConversion}}(Makie.NoDimConversion()), Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing), ), ), ) ``` EDIT3: So the function above is called with different arguments each time. That comes from here: https://github.com/MakieOrg/Makie.jl/blob/4a6728146ca4d5b3d20ee9244300788243697c79/Makie/src/figureplotting.jl#L401-L403 On line 403 you see the call to the function above, and on line 401 you can see how the arguments are generated. They are different the first and the second time, because `ax` is a stateful Axis object and `get_conversions(ax)` returns different things each time. We can see that by doing: ``` f = Figure() ax = Axis(f[1,1]) Makie.get_conversions(ax) # Makie.DimConversions((Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing), Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing), Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing))) plot!(ax, y1) Makie.get_conversions(ax) # Makie.DimConversions((Observable{Union{Nothing, Makie.AbstractDimConversion}}(Makie.DateTimeConversion(Observable(DateTime))), Observable{Union{Nothing, Makie.AbstractDimConversion}}(Makie.NoDimConversion()), Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing))) plot!(ax, y2) ``` EDIT4: Ok dim conversions being different in first and second calling of plot! isn't the reason for this problem, because the simple case: ``` ts = DateTime("2026-01-01"):Minute(1):DateTime("2026-01-01T00:10:00") y1 = rand(Float64, 11) y2 = rand(Float64, 11) f = Figure() ax = Axis(f[1,1]) plot!(ax, ts, y1) # Scatter{Tuple{Vector{Point{2, Float64}}}} plot!(ax, ts, y2) # Scatter{Tuple{Vector{Point{2, Float64}}}} ``` Has the same behavior. Help? I have no idea what I'm doing here.
2 条评论