Makie.jl icon indicating copy to clipboard operation
Makie.jl copied to clipboard

Synchronous updates problem with contourf

Open yakir12 opened this issue 3 years ago • 2 comments

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

yakir12 avatar Jul 21 '22 09:07 yakir12

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.

jkrumbiegel avatar Jul 21 '22 10:07 jkrumbiegel

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.

yakir12 avatar Jul 21 '22 13:07 yakir12