Error in updating histogram using Textbox in GLMakie

Hello,

I am trying to use the Textbox option with GLMakie for histograms and in particular to change the binning of the data. Here’s the code I’m using:

using GLMakie
using FHist

fig = Figure()

tb = Textbox(fig, placeholder = "Enter binedges",
     tellwidth = false)     

fig[1,1] = vgrid!(
    Label(fig, "Binedges", width=nothing),
    tb;
    tellheight=false
)

X = randn(1000)
binedges_obs = Observable(-10:1:10)
h = @lift(Hist1D(X, binedges=$binedges_obs))
hist(fig[1,2], h)

# input binedges
on(tb.stored_string) do s
    # convert binedges from string into StepRange
    prs = parse.(Int, split(s,":"))
    start = prs[1]
    step = prs[2]
    stop = prs[3]
    binedges_obs[] = StepRange(start, step, stop)
end

fig

When I execute the code, it works normally. However, as soon as I try a different binning in the textbox, I get the following error:

julia> Error in callback:
DimensionMismatch: arrays could not be broadcast to a common size; got a dimension with lengths 10 and 20
Stacktrace:
  [1] _bcs1
    @ .\broadcast.jl:555 [inlined]
  [2] _bcs
    @ .\broadcast.jl:549 [inlined]
  [3] broadcast_shape
    @ .\broadcast.jl:543 [inlined]
  [4] combine_axes
    @ .\broadcast.jl:524 [inlined]
  [5] instantiate
    @ .\broadcast.jl:306 [inlined]
  [6] materialize
    @ .\broadcast.jl:903 [inlined]
  [7] compute_x_and_width(x::Vector{Float64}, width::Vector{Float64}, gap::Int64, dodge::Makie.Automatic, n_dodge::Makie.Automatic, dodge_gap::Float64)
    @ Makie C:\Users\georg\.julia\packages\Makie\4JW9B\src\basic_recipes\barplot.jl:115
  [8] (::Makie.var"#calculate_bars#892"{Observable{Vector{ColorTypes.RGBA{Float32}}}, Observable{Vector{Vec{2, Float64}}}, Observable{Vector{Vec{2, Float64}}}, Observable{Vector{Tuple{Union{String, LaTeXStrings.LaTeXString}, Point{2, Float64}}}}})(xy::Vector{Point{2, Float64}}, fillto::Float64, offset::Float64, transformation::Tuple{typeof(identity), typeof(identity)}, width::Vector{Float64}, dodge::Makie.Automatic, n_dodge::Makie.Automatic, gap::Int64, dodge_gap::Float64, stack::Makie.Automatic, dir::Symbol, bar_labels::Nothing, flip_labels_at::Float64, label_color::Symbol, color_over_background::Makie.Automatic, color_over_bar::Makie.Automatic, label_formatter::typeof(Makie.bar_label_formatter), label_offset::Int64, label_rotation::Float64, label_align::Makie.Automatic, label_position::Symbol)  
    @ Makie C:\Users\georg\.julia\packages\Makie\4JW9B\src\basic_recipes\barplot.jl:296
  [9] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
    @ Base .\essentials.jl:892
 [10] invokelatest(::Any, ::Any, ::Vararg{Any})
    @ Base .\essentials.jl:889
 [11] (::Observables.MapCallback)(value::Any)
    @ Observables C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:436
 [12] #invokelatest#2
    @ .\essentials.jl:892 [inlined]
 [13] invokelatest
    @ .\essentials.jl:889 [inlined]
 [14] notify
    @ C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:206 [inlined]
 [15] (::ComputePipeline.var"#37#38"{ComputePipeline.ComputeGraph})(changeset::Set{Symbol})
    @ ComputePipeline C:\Users\georg\.julia\packages\ComputePipeline\03tW7\src\ComputePipeline.jl:351
 [16] #invokelatest#2
    @ .\essentials.jl:892 [inlined]
 [17] invokelatest
    @ .\essentials.jl:889 [inlined]
 [18] notify
    @ C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:206 [inlined]
 [19] foreach(f::typeof(notify), itr::Vector{Observable})
    @ Base .\abstractarray.jl:3098
 [20] #39
    @ C:\Users\georg\.julia\packages\ComputePipeline\03tW7\src\ComputePipeline.jl:501 [inlined]      
 [21] lock(f::ComputePipeline.var"#39#40"{ComputePipeline.ComputeGraph, Symbol, Hist1D{Float64}}, l::ReentrantLock)
    @ Base .\lock.jl:229
 [22] setproperty!
    @ C:\Users\georg\.julia\packages\ComputePipeline\03tW7\src\ComputePipeline.jl:499 [inlined]      
 [23] (::ComputePipeline.var"#57#58"{ComputePipeline.ComputeGraph, Symbol})(new_val::Hist1D{Float64})
    @ ComputePipeline C:\Users\georg\.julia\packages\ComputePipeline\03tW7\src\ComputePipeline.jl:783
 [24] #invokelatest#2
    @ .\essentials.jl:892 [inlined]
 [25] invokelatest
    @ .\essentials.jl:889 [inlined]
 [26] notify
    @ C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:206 [inlined]
 [27] setindex!(observable::Observable, val::Any)
    @ Observables C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:123
 [28] (::Observables.MapCallback)(value::Any)
    @ Observables C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:436
 [29] #invokelatest#2
    @ .\essentials.jl:892 [inlined]
 [30] invokelatest
    @ .\essentials.jl:889 [inlined]
 [31] notify
    @ C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:206 [inlined]
 [32] setindex!(observable::Observable, val::Any)
    @ Observables C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:123
 [33] (::var"#17#18")(s::String)
    @ Main c:\Users\georg\OneDrive\Documents\NEWSG\SPCAnalysisTools\scripts\test.jl:27
 [34] #invokelatest#2
    @ .\essentials.jl:892 [inlined]
 [35] invokelatest
    @ .\essentials.jl:889 [inlined]
 [36] notify
    @ C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:206 [inlined]
 [37] setindex!(observable::Observable, val::Any)
    @ Observables C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:123
 [38] (::Makie.var"#2836#2863"{Textbox, Makie.var"#cursor_backward#2862"{Observable{Int64}}, Makie.var"#cursor_forward#2861"{Textbox, Observable{Int64}}, Makie.var"#removechar!#2858"{Textbox, Observable{Vector{Char}}, Observable{Int64}}, Makie.var"#insertchar!#2856"{Textbox, Observable{Vector{Char}}, Observable{Int64}}, Observable{Bool}, Observable{Int64}, Scene})(event::Makie.KeyEvent)
    @ Makie C:\Users\georg\.julia\packages\Makie\4JW9B\src\makielayout\blocks\textbox.jl:293
 [39] #invokelatest#2
    @ .\essentials.jl:892 [inlined]
 [40] invokelatest
    @ .\essentials.jl:889 [inlined]
 [41] notify
    @ C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:206 [inlined]
 [42] setindex!
    @ C:\Users\georg\.julia\packages\Observables\YdEbO\src\Observables.jl:123 [inlined]
 [43] (::GLMakie.var"#keyoardbuttons#153"{Observable{Makie.KeyEvent}})(window::GLFW.Window, button::GLFW.Key, scancode::Int32, action::GLFW.Action, mods::Int32)
    @ GLMakie C:\Users\georg\.julia\packages\GLMakie\6el3D\src\events.jl:118
 [44] _KeyCallbackWrapper(window::GLFW.Window, key::GLFW.Key, scancode::Int32, action::GLFW.Action, mods::Int32)
    @ GLFW C:\Users\georg\.julia\packages\GLFW\Zwulj\src\callback.jl:46
 [45] macro expansion
    @ C:\Users\georg\.julia\packages\GLFW\Zwulj\src\GLFW.jl:34 [inlined]
 [46] PollEvents
    @ C:\Users\georg\.julia\packages\GLFW\Zwulj\src\glfw3.jl:753 [inlined]
 [47] pollevents(screen::GLMakie.Screen{GLFW.Window}, frame_state::Makie.TickState)
    @ GLMakie C:\Users\georg\.julia\packages\GLMakie\6el3D\src\screen.jl:559
 [48] (::GLMakie.var"#96#97"{GLMakie.Screen{GLFW.Window}})()
    @ GLMakie C:\Users\georg\.julia\packages\GLMakie\6el3D\src\screen.jl:1092
 [49] with_context(f::GLMakie.var"#96#97"{GLMakie.Screen{GLFW.Window}}, context::GLFW.Window)        
    @ GLMakie.GLAbstraction C:\Users\georg\.julia\packages\GLMakie\6el3D\src\GLAbstraction\GLAbstraction.jl:59
 [50] on_demand_renderloop(screen::GLMakie.Screen{GLFW.Window})
    @ GLMakie C:\Users\georg\.julia\packages\GLMakie\6el3D\src\screen.jl:1091
 [51] renderloop(screen::GLMakie.Screen{GLFW.Window})
    @ GLMakie C:\Users\georg\.julia\packages\GLMakie\6el3D\src\screen.jl:1119

In the particular case, I tried to change the binning by putting in the textbox -5:1:5.
I observed though that if the new binning produces same number of bins, I don’t get an error but I don’t see any change in the histogram either.

Could you please help?

Thanks

Is that on Makie 0.24 or older than that? Because updating to data of other shapes should in general be more reliable on 0.24.

It’s on Makie 0.24.6 and the GLMakie is 0.13.6

Looks like barplot is not yet updated fully to the compute graph, your error appears in this lift statement Makie.jl/Makie/src/basic_recipes/barplot.jl at 10d65fd67bb269ea96c6748d754fd3544bb3051c · MakieOrg/Makie.jl · GitHub

tracking it back, it looks like the problem happens in Makie.jl/Makie/src/basic_recipes/barplot.jl at 10d65fd67bb269ea96c6748d754fd3544bb3051c · MakieOrg/Makie.jl · GitHub and in particular during broadcasting in the return x .+ width .* shifts, width * dodge_width statement.

yes because the lift runs once the first observable is updated, when it’s moved over to compute pipeline the update of all attributes should happen synchronously when the backend requests it.

You could try and see if changing to a compute graph update fixes things, you can look at other recipes in Makie to see how that works, for example here Makie.jl/Makie/src/basic_recipes/error_and_rangebars.jl at 10d65fd67bb269ea96c6748d754fd3544bb3051c · MakieOrg/Makie.jl · GitHub

I see. Ok I’ll try it
Thanks