Makie.jl
Makie.jl copied to clipboard
Synchronous updates problem with contourf
This is a yet-another-synchronous-update problem. I'm mainly submitting this issue for book-keeping purposes. This specific example concerns contourf:
xs = Observable(1:10)
ys = Observable(1:10)
img = Observable(rand(10,10))
contourf(xs, ys, img)
# now I want to update the x, y, and image values:
xs.val = 1:5 # careful...
ys.val = 1:5 # good...
img[] = rand(5,5) # error!
The trace is:
julia> img[] = rand(5,5)
ERROR: Length of x (5) must be equal to number of columns in z (10)
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] isobands(xs::Vector{Float64}, ys::Vector{Float64}, zs::Matrix{Float64}, low_values::Vector{Float64}, high_values::Vector{Float64})
@ Isoband ~/.julia/packages/Isoband/qUEGP/src/Isoband.jl:56
[3] isobands(xs::Vector{Float32}, ys::Vector{Float32}, zs::LinearAlgebra.Adjoint{Float32, Matrix{Float32}}, lows::Vector{Float32}, highs::Vector{Float32})
@ Isoband ~/.julia/packages/Isoband/qUEGP/src/Isoband.jl:32
[4] (::Makie.var"#calculate_polys#439"{Observable{Vector{Float64}}, Observable{Vector{GeometryBasics.Polygon{2, Float32, Point{2, Float32}, GeometryBasics.LineString{2, Float32, Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{Point{2, Float32}, Point{2, Float32}}, GeometryBasics.TupleView{Tuple{Point{2, Float32}, Point{2, Float32}}, 2, 1, Vector{Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{Point{2, Float32}, Point{2, Float32}}, GeometryBasics.TupleView{Tuple{Point{2, Float32}, Point{2, Float32}}, 2, 1, Vector{Point{2, Float32}}}, false}}}}}}})(xs::Vector{Float32}, ys::Vector{Float32}, zs::Matrix{Float32}, levels::Vector{Float32}, is_extended_low::Bool, is_extended_high::Bool)
@ Makie ~/.julia/packages/Makie/6TJFL/src/basic_recipes/contourf.jl:132
[5] (::Observables.var"#callback#13"{Makie.var"#calculate_polys#439"{Observable{Vector{Float64}}, Observable{Vector{GeometryBasics.Polygon{2, Float32, Point{2, Float32}, GeometryBasics.LineString{2, Float32, Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{Point{2, Float32}, Point{2, Float32}}, GeometryBasics.TupleView{Tuple{Point{2, Float32}, Point{2, Float32}}, 2, 1, Vector{Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{Point{2, Float32}, Point{2, Float32}}, GeometryBasics.TupleView{Tuple{Point{2, Float32}, Point{2, Float32}}, 2, 1, Vector{Point{2, Float32}}}, false}}}}}}}, Tuple{Observable{Vector{Float32}}, Observable{Vector{Float32}}, Observable{Matrix{Float32}}, Observable{Any}, Observable{Bool}, Observable{Bool}}})(x::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:339
[6] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[7] invokelatest
@ ./essentials.jl:726 [inlined]
[8] notify
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:143 [inlined]
[9] setindex!(observable::Observable, val::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:86
[10] #15
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:393 [inlined]
[11] (::Observables.var"#callback#13"{Observables.var"#15#16"{Makie.var"#117#119"{Int64}, Observable{Vector{Float32}}}, Tuple{Observable{Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float32}}}}})(x::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:339
[12] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[13] invokelatest
@ ./essentials.jl:726 [inlined]
[14] notify
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:143 [inlined]
[15] setindex!(observable::Observable, val::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:86
[16] (::Makie.var"#130#132"{Attributes, Observable{Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float32}}}, DataType})(kwargs::Tuple{}, args::Tuple{UnitRange{Int64}, UnitRange{Int64}, Matrix{Float64}})
@ Makie ~/.julia/packages/Makie/6TJFL/src/interfaces.jl:318
[17] (::Observables.var"#callback#13"{Makie.var"#130#132"{Attributes, Observable{Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float32}}}, DataType}, Tuple{Observable{Tuple{}}, Observable{Tuple{UnitRange{Int64}, UnitRange{Int64}, Matrix{Float64}}}}})(x::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:339
[18] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[19] invokelatest
@ ./essentials.jl:726 [inlined]
[20] notify
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:143 [inlined]
[21] setindex!(observable::Observable, val::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:86
[22] #15
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:393 [inlined]
[23] (::Observables.var"#callback#13"{Observables.var"#15#16"{typeof(tuple), Observable{Tuple{UnitRange{Int64}, UnitRange{Int64}, Matrix{Float64}}}}, Tuple{Observable{UnitRange{Int64}}, Observable{UnitRange{Int64}}, Observable{Matrix{Float64}}}})(x::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:339
[24] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[25] invokelatest
@ ./essentials.jl:726 [inlined]
[26] notify
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:143 [inlined]
[27] setindex!(observable::Observable, val::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:86
[28] top-level scope
@ REPL[36]:1
I think the problem with these is that the input arguments have one more indirection which is the conversion. The Int ranges will probably be converted to Float32 Vectors and so your .val update doesn't reach the converted ones. Just to confirm, can you try the same thing but x and y should contain Vector{Float32}? And maybe you even need to mutate the inner vectors instead of replace them, try it out.
No, this:
xs = Observable{Vector{Float32}}(Float32.(1:10))
ys = Observable{Vector{Float32}}(Float32.(1:10))
img = Observable(rand(10,10))
contourf(xs, ys, img)
# now I want to update the x, y, and image values:
empty!(xs.val)
append!(xs.val, 1:5)
empty!(ys.val)
append!(ys.val, 1:5)
which still is a Float32 Vector:
julia> typeof(xs)
Observable{Vector{Float32}}
didn't work:
img[] = rand(5,5)
ERROR: Length of x (5) must be equal to number of columns in z (10)
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] isobands(xs::Vector{Float64}, ys::Vector{Float64}, zs::Matrix{Float64}, low_values::Vector{Float64}, high_values::Vector{Float64})
@ Isoband ~/.julia/packages/Isoband/qUEGP/src/Isoband.jl:56
[3] isobands(xs::Vector{Float32}, ys::Vector{Float32}, zs::LinearAlgebra.Adjoint{Float32, Matrix{Float32}}, lows::Vector{Float32}, highs::Vector{Float32})
@ Isoband ~/.julia/packages/Isoband/qUEGP/src/Isoband.jl:32
[4] (::Makie.var"#calculate_polys#439"{Observable{Vector{Float64}}, Observable{Vector{GeometryBasics.Polygon{2, Float32, Point{2, Float32}, GeometryBasics.LineString{2, Float32, Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{Point{2, Float32}, Point{2, Float32}}, GeometryBasics.TupleView{Tuple{Point{2, Float32}, Point{2, Float32}}, 2, 1, Vector{Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{Point{2, Float32}, Point{2, Float32}}, GeometryBasics.TupleView{Tuple{Point{2, Float32}, Point{2, Float32}}, 2, 1, Vector{Point{2, Float32}}}, false}}}}}}})(xs::Vector{Float32}, ys::Vector{Float32}, zs::Matrix{Float32}, levels::Vector{Float32}, is_extended_low::Bool, is_extended_high::Bool)
@ Makie ~/.julia/packages/Makie/6TJFL/src/basic_recipes/contourf.jl:132
[5] (::Observables.var"#callback#13"{Makie.var"#calculate_polys#439"{Observable{Vector{Float64}}, Observable{Vector{GeometryBasics.Polygon{2, Float32, Point{2, Float32}, GeometryBasics.LineString{2, Float32, Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{Point{2, Float32}, Point{2, Float32}}, GeometryBasics.TupleView{Tuple{Point{2, Float32}, Point{2, Float32}}, 2, 1, Vector{Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{Point{2, Float32}, Point{2, Float32}}, GeometryBasics.TupleView{Tuple{Point{2, Float32}, Point{2, Float32}}, 2, 1, Vector{Point{2, Float32}}}, false}}}}}}}, Tuple{Observable{Vector{Float32}}, Observable{Vector{Float32}}, Observable{Matrix{Float32}}, Observable{Any}, Observable{Bool}, Observable{Bool}}})(x::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:339
[6] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[7] invokelatest
@ ./essentials.jl:726 [inlined]
[8] notify
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:143 [inlined]
[9] setindex!(observable::Observable, val::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:86
[10] #15
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:393 [inlined]
[11] (::Observables.var"#callback#13"{Observables.var"#15#16"{Makie.var"#117#119"{Int64}, Observable{Vector{Float32}}}, Tuple{Observable{Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float32}}}}})(x::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:339
[12] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[13] invokelatest
@ ./essentials.jl:726 [inlined]
[14] notify
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:143 [inlined]
[15] setindex!(observable::Observable, val::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:86
[16] (::Makie.var"#130#132"{Attributes, Observable{Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float32}}}, DataType})(kwargs::Tuple{}, args::Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float64}})
@ Makie ~/.julia/packages/Makie/6TJFL/src/interfaces.jl:318
[17] (::Observables.var"#callback#13"{Makie.var"#130#132"{Attributes, Observable{Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float32}}}, DataType}, Tuple{Observable{Tuple{}}, Observable{Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float64}}}}})(x::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:339
[18] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[19] invokelatest
@ ./essentials.jl:726 [inlined]
[20] notify
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:143 [inlined]
[21] setindex!(observable::Observable, val::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:86
[22] #15
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:393 [inlined]
[23] (::Observables.var"#callback#13"{Observables.var"#15#16"{typeof(tuple), Observable{Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float64}}}}, Tuple{Observable{Vector{Float32}}, Observable{Vector{Float32}}, Observable{Matrix{Float64}}}})(x::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:339
[24] #invokelatest#2
@ ./essentials.jl:729 [inlined]
[25] invokelatest
@ ./essentials.jl:726 [inlined]
[26] notify
@ ~/.julia/packages/Observables/ynr7h/src/Observables.jl:143 [inlined]
[27] setindex!(observable::Observable, val::Any)
@ Observables ~/.julia/packages/Observables/ynr7h/src/Observables.jl:86
[28] top-level scope
@ REPL[306]:1
Note issue #2159 which must be related.