JuliaGizmos / InteractBase.jl

Build interactive HTML5 widgets in Julia
Other
27 stars 23 forks source link

Strange behaviours of slider() with arrays of negative numbers #121

Closed rafaqz closed 5 years ago

rafaqz commented 5 years ago

Describe the bug A clear and concise description of what the bug is.

Sliders do not accept arrays containing negative numbers larger than -21 when a value keyword is used. I couldn't track down exactly where this is happening.

To Reproduce Steps to reproduce the behavior.

julia> InteractBase.slider(collect(0.0:-1.0:-25.0), value=-10.0)
ERROR: BoundsError: attempt to access 26-element Array{String,1} at index [27]
Stacktrace:
 [1] ./array.jl:731
 [2] /home/raf/.julia/dev/InteractBase/src/slider.jl:68
 [3] ./none:0
 [4] /home/raf/.julia/dev/InteractBase/src/slider.jl:24
 [5] ./simdloop.jl:0 [inlined]
 [6] ./none:0
 [7] /home/raf/.julia/dev/InteractBase/src/defaults.jl:12
 [8] ./none:0
 [9] none:0

Expected behavior A clear and concise description of what you expected to happen.

Return a slider! As with InteractBase.slider(collect(0.0:-1.0:-20.0), value=-10.0) or any positive numbers.

Interestingly this works if the first number in the array is larger than some distance from the minimum negative val:

julia>             InteractBase.slider(collect(2.0:-1.0:-24.0), value=-10.0)
ERROR: BoundsError: attempt to access 27-element Array{String,1} at index [28]
Stacktrace:
 [1] getindex(::Array{String,1}, ::Int64) at ./array.jl:731
 [2] #slider#75(::String, ::String, ::Observables.Observable{Any}, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::NativeHTML, ::Base.OneTo{Int64}, ::Array{String,1}) at /home/raf/.julia/dev/InteractBase/src/slider.jl:68
 [3] (::getfield(InteractBase, Symbol("#kw##slider")))(::NamedTuple{(:value,),Tuple{Observables.Observable{Any}}}, ::typeof(slider), ::NativeHTML, ::Base.OneTo{Int64}, ::Array{String,1}) at ./none:0
 [4] #slider#67(::Float64, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::NativeHTML, ::Array{Float64,1}, ::Array{String,1}) at /home/raf/.julia/dev/InteractBase/src/slider.jl:24
 [5] #slider at ./simdloop.jl:0 [inlined]
 [6] (::getfield(InteractBase, Symbol("#kw##slider")))(::NamedTuple{(:value,),Tuple{Float64}}, ::typeof(slider), ::NativeHTML, ::Array{Float64,1}) at ./none:0
 [7] #slider#170(::Base.Iterators.Pairs{Symbol,Float64,Tuple{Symbol},NamedTuple{(:value,),Tuple{Float64}}}, ::Function, ::Array{Float64,1}) at /home/raf/.julia/dev/InteractBase/src/defaults.jl:12
 [8] (::getfield(InteractBase, Symbol("#kw##slider")))(::NamedTuple{(:value,),Tuple{Float64}}, ::typeof(slider), ::Array{Float64,1}) at ./none:0
 [9] top-level scope at none:0

But:

julia>             InteractBase.slider(collect(3.0:-1.0:-24.0), value=-10.0)
Widget{:slider,Float64}(OrderedCollections.OrderedDict{Symbol,Any}(:changes=>Observable{Int64} with 1 listeners. Value:
0,:index=>Observable{Any} with 2 listeners. Value:
1,:formatted_vals=>Observable{Any} with 1 listeners. Value:
...

Screenshots If applicable, add screenshots to help explain your problem.

Version info (please complete the following information):

Julia Version 1.0.2 Commit d789231e99 (2018-11-08 20:11 UTC) Platform Info: OS: Linux (x86_64-pc-linux-gnu) CPU: Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz WORD_SIZE: 64 LIBM: libopenlibm LLVM: libLLVM-6.0.0 (ORCJIT, skylake) Environment: JULIA_NUM_THREADS = 5 julia> Pkg.status() Status ~/.julia/environments/v1.0/Project.toml [f5f396d3] ApproxBayes v0.3.0 [c9ce4bd3] ArchGDAL v0.2.0 [bf4720bc] AssetRegistry v0.1.0 [6e4b80f9] BenchmarkTools v0.4.2 [ad839575] Blink v0.9.0 [70588ee8] CSSUtil v0.1.0 [159f3aea] Cairo v0.5.6 [a5dba43e] Cellular v0.0.0 [~/julia/Cellular] [5ae59095] Colors v0.9.5 [a8cc5b0e] Crayons v1.0.0 [a93c6f00] DataFrames v0.17.0 [ab62b9b5] DeepDiffs v1.1.0 [0c46a032] DifferentialEquations v5.3.1 [72d8b834] Dispersal v0.0.0 [~/julia/Dispersal] [31c24e10] Distributions v0.16.4 [6ffd65d2] DynamicEnergyBudgets v0.0.0 [~/julia/DynamicEnergyBudgets] [49426c49] FieldDefaults v0.0.1+ [~/julia/FieldDefaults] [bf96fef3] FieldMetadata v0.0.3+ [~/julia/FieldMetadata] [4c728ea3] Flatten v0.1.0+ [~/julia/Flatten] [4c0ca9eb] Gtk v0.16.4 [f67ccb44] HDF5 v0.11.0 [6218d12a] ImageMagick v0.7.1 [916415d5] Images v0.17.0 [c601a237] Interact v0.9.0 [d3863d7c] InteractBase v0.8.2+ [~/.julia/dev/InteractBase] [7981ab7d] InteractBulma v0.4.2 [033835bb] JLD2 v0.1.2 [2ee39098] LabelledArrays v0.4.0+ [~/.julia/dev/LabelledArrays] [23fbe1c1] Latexify v0.6.0 [e0eb800d] Microclimate v0.0.0 [~/julia/Microclimate] [2a8e4939] Mixers v0.1.0+ [~/julia/Mixers] [a975b10e] Mux v0.5.3 [85f8d34a] NCDatasets v0.6.0 [30363a11] NetCDF v0.7.2 [f7c12bf4] NicheMap v0.0.0 [~/julia/NicheMap] [510215fc] Observables v0.2.3 [6fe1bfb0] OffsetArrays v0.9.1 [5fb14364] OhMyREPL v0.4.1 [429524aa] Optim v0.17.2 [1dea7af3] OrdinaryDiffEq v4.21.1 [d96e819e] Parameters v0.10.3 [5e10c064] Photosynthesis v0.0.0 [~/julia/Photosynthesis] [48f930ff] PlotNested v0.0.0 [~/julia/PlotNested] [91a5bcdd] Plots v0.23.0 [c46f51b8] ProfileView v0.4.0 [061b77f0] REPLGamesBase v0.1.0 #master (https://github.com/ChristianKurz/REPLGamesBase.jl) [ae029012] Requires v0.5.2 [295af30f] Revise v1.0.2+ [~/.julia/dev/Revise] [eac7fb6e] ReviseTest v0.0.0 [~/.julia/dev/ReviseTest] [1bc83da4] SafeTestsets v0.0.1 [6accb78c] SimpleRoots v0.0.0 [~/julia/SimpleRoots] [90137ffa] StaticArrays v0.10.2 [f3b207a7] StatsPlots v0.10.0 [eb3e9d2b] StructuralInheritance v0.2.4 [a759f4b9] TimerOutputs v0.4.0 [9d95f2ec] TypedTables v1.1.0 [ebadf6b4] UnicodeGraphics v0.0.1+ [~/julia/UnicodeGraphics] [1986cc42] Unitful v0.14.0+ [~/.julia/dev/Unitful] [2a06ce6d] UnitfulPlots v0.0.0 [~/julia/UnitfulPlots] [03de777c] UnitlessFlatten v0.0.1+ [~/julia/UnitlessFlatten] [0f1e0344] WebIO v0.7.0 [104b5d7c] WebSockets v1.2.0 [cc8bc4a8] Widgets v0.4.4

Before opening an issue

If widgets do not appear

rafaqz commented 5 years ago

Ok so the issue is with the return result of ObservablePair with those f and g values, but the logic is kind of hard to follow through the anonymous functions and ObservablePair...

https://github.com/piever/InteractBase.jl/blob/master/src/slider.jl#L19-L23

maybe this needs rev=true on searchsortedfirst when the array order is reversed?

Edit: just to explain why a reversed order is needed, some environmental measures like soil water potential are measured in kPa from 0.0:-10000. You really want zero at the start of the slider and the "large" values at the end, so its intuitively similar to the other sliders. This means reverse order. And a vector is needed over a range if you want log scaling.

piever commented 5 years ago

Thanks for such a detailed issue report! Yes, the code should definitely use some simplification (though it's hard to account for all cases). I simply didn't take into account that ranges could be in reverse order. value and index (the index of the value in the range of values) are an ObservablePair (which means if you change one the other updates): the error here is that I use searchsortedfirst to get the index from the value which fails if the vector is not sorted. It should be easy to fix though.

piever commented 5 years ago

Does https://github.com/piever/InteractBase.jl/pull/122 fix your use case?

rafaqz commented 5 years ago

Thanks! #122 works fine