MakieOrg / Makie.jl

Interactive data visualizations and plotting in Julia
https://docs.makie.org/stable
MIT License
2.37k stars 302 forks source link

Zooming in too much breaks the plot #4064

Open EdsterG opened 1 month ago

EdsterG commented 1 month ago

Are you running newest version (version from docs) ?

0.21.8

Can you reproduce the bug with a fresh environment ? (]activate --temp; add Makie)

Yes

What platform + GPU are you on?

MacOS

A couple times I had accidentally zoomed in too much and the broke the plot. I would expect the plot to be robust to various zoom levels.

Easy to recreate, plot the following and zoom an extreme amount.

using WGLMakie

scatter(1:4, color=1:4)

When zooming in:

┌ Warning: Error in window event callback
│   exception =
│    ArgumentError: range step cannot be zero
│    Stacktrace:
│      [1] Colon
│        @ ./twiceprecision.jl:394
│      [2] get_minor_tickvalues(i::Makie.IntervalsBetween, scale::Function, tickvalues::Vector{Float64}, vmin::Float64, vmax::Float64)
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/lineaxis.jl:721
│      [3] (::Makie.var"#1597#1611"{MakieCore.Attributes, Observables.Observable{Vector{Float64}}, Observables.Observable{Tuple{Float64, Float64}}})(tickvalues::Vector{Float64}, minorticks::Makie.IntervalsBetween)
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/lineaxis.jl:437
│      [4] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
│        @ Base ./essentials.jl:892
│      [5] invokelatest(::Any, ::Any, ::Vararg{Any})
│        @ Base ./essentials.jl:889
│      [6] (::Observables.OnAny)(value::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:420
│      [7] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│      [8] invokelatest
│        @ ./essentials.jl:889 [inlined]
│      [9] notify
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
│     [10] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
│     [11] update_tickpos_string(closure_args::Tuple{Observables.Observable{Vector{Any}}, Observables.Observable{Vector{GeometryBasics.Point{2, Float32}}}, Observables.Observable{Vector{Float64}}, Observables.Observable{Tuple{Float32, Tuple{Float32, Float32}, Bool}}, Observables.Observable{Tuple{Float64, Float64}}}, tickvalues_labels_unfiltered::Tuple{Vector{Float64}, Vector{Any}}, reversed::Bool, scale::typeof(identity))
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/lineaxis.jl:213
│     [12] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
│        @ Base ./essentials.jl:892
│     [13] invokelatest(::Any, ::Any, ::Vararg{Any})
│        @ Base ./essentials.jl:889
│     [14] (::Observables.OnAny)(value::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:420
│     [15] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [16] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [17] notify
│        @ [~/.julia/packages/Observables/YdEbO/src/Observables.jl:206](http://localhost:7777/home/user/.julia/packages/Observables/YdEbO/src/Observables.jl#line=205) [inlined]
│     [18] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
│     [19] (::Observables.MapCallback)(value::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:436
│    --- the last 5 lines are repeated 1 more time ---
│     [25] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [26] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [27] notify
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
│     [28] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
│     [29] (::Observables.SetindexCallback)(x::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:148
│     [30] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [31] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [32] notify
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
│     [33] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
│     [34] (::Observables.MapCallback)(value::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:436
│     [35] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [36] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [37] notify
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
│     [38] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
│     [39] adjustlimits!(la::Makie.Axis)
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:990
│     [40] (::Makie.var"#1658#1689"{Makie.Axis})(pxa::GeometryBasics.HyperRectangle{2, Int64}, lims::GeometryBasics.HyperRectangle{2, Float64})
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:507
│     [41] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
│        @ Base ./essentials.jl:892
│     [42] invokelatest(::Any, ::Any, ::Vararg{Any})
│        @ Base ./essentials.jl:889
│     [43] (::Observables.OnAny)(value::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:420
│     [44] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [45] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [46] notify
│        @ [~/.julia/packages/Observables/YdEbO/src/Observables.jl:206](http://localhost:7777/home/user/.julia/packages/Observables/YdEbO/src/Observables.jl#line=205) [inlined]
│     [47] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
│     [48] process_interaction(s::Makie.ScrollZoom, event::Makie.ScrollEvent, ax::Makie.Axis)
│        @ Makie [~/.julia/packages/Makie/rEu75/src/makielayout/interactions.jl:287](http://localhost:7777/home/user/.julia/packages/Makie/rEu75/src/makielayout/interactions.jl#line=286)
│     [49] process_axis_event(ax::Makie.Axis, event::Makie.ScrollEvent)
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:15
│     [50] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
│        @ Base ./essentials.jl:892
│     [51] invokelatest(::Any, ::Any, ::Vararg{Any})
│        @ Base ./essentials.jl:889
│     [52] (::Observables.OnAny)(value::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:420
│     [53] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [54] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [55] notify
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
│     [56] setindex!
│        @ [~/.julia/packages/Observables/YdEbO/src/Observables.jl:123](http://localhost:7777/home/user/.julia/packages/Observables/YdEbO/src/Observables.jl#line=122) [inlined]
│     [57] (::Makie.var"#1623#1625"{Makie.Scene, Observables.Observable{Makie.ScrollEvent}})(s::Tuple{Float64, Float64})
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:33
│     [58] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [59] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [60] notify
│        @ [~/.julia/packages/Observables/YdEbO/src/Observables.jl:206](http://localhost:7777/home/user/.julia/packages/Observables/YdEbO/src/Observables.jl#line=205) [inlined]
│     [61] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
└ @ WGLMakie ~/.julia/packages/WGLMakie/7QQ6J/src/events.jl:112

After zooming in too much the plot is forever stuck with the following output:

┌ Warning: Error in window event callback
│   exception =
│    AssertionError: all(low .<= high)
│    Stacktrace:
│      [1] update_limits!(c::Makie.Float32Convert, mini::GeometryBasics.Vec{3, Float64}, maxi::GeometryBasics.Vec{3, Float64})
│        @ Makie ~/.julia/packages/Makie/rEu75/src/float32-scaling.jl:129
│      [2] update_limits!
│        @ ~/.julia/packages/Makie/rEu75/src/float32-scaling.jl:109 [inlined]
│      [3] update_axis_camera(scene::Makie.Scene, t::Tuple{typeof(identity), typeof(identity)}, lims::GeometryBasics.HyperRectangle{2, Float64}, xrev::Bool, yrev::Bool)
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:71
│      [4] (::Makie.var"#1631#1662"{Makie.Scene})(::Tuple{typeof(identity), typeof(identity)}, ::Vararg{Any})
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:255
│      [5] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
│        @ Base ./essentials.jl:892
│      [6] invokelatest(::Any, ::Any, ::Vararg{Any})
│        @ Base ./essentials.jl:889
│      [7] (::Observables.OnAny)(value::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:420
│      [8] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│      [9] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [10] notify
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
│     [11] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
│     [12] adjustlimits!(la::Makie.Axis)
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:990
│     [13] (::Makie.var"#1658#1689"{Makie.Axis})(pxa::GeometryBasics.HyperRectangle{2, Int64}, lims::GeometryBasics.HyperRectangle{2, Float64})
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:507
│     [14] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
│        @ Base ./essentials.jl:892
│     [15] invokelatest(::Any, ::Any, ::Vararg{Any})
│        @ Base ./essentials.jl:889
│     [16] (::Observables.OnAny)(value::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:420
│     [17] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [18] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [19] notify
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
│     [20] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
│     [21] process_interaction(s::Makie.ScrollZoom, event::Makie.ScrollEvent, ax::Makie.Axis)
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/interactions.jl:287
│     [22] process_axis_event(ax::Makie.Axis, event::Makie.ScrollEvent)
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:15
│     [23] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
│        @ Base ./essentials.jl:892
│     [24] invokelatest(::Any, ::Any, ::Vararg{Any})
│        @ Base ./essentials.jl:889
│     [25] (::Observables.OnAny)(value::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:420
│     [26] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [27] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [28] notify
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
│     [29] setindex!
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123 [inlined]
│     [30] (::Makie.var"#1623#1625"{Makie.Scene, Observables.Observable{Makie.ScrollEvent}})(s::Tuple{Float64, Float64})
│        @ Makie ~/.julia/packages/Makie/rEu75/src/makielayout/blocks/axis.jl:33
│     [31] #invokelatest#2
│        @ ./essentials.jl:892 [inlined]
│     [32] invokelatest
│        @ ./essentials.jl:889 [inlined]
│     [33] notify
│        @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
│     [34] setindex!(observable::Observables.Observable, val::Any)
│        @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
│     [35] (::WGLMakie.var"#60#62"{Dict{Any, Any}, Makie.Scene, Makie.Events})()
│        @ WGLMakie ~/.julia/packages/WGLMakie/7QQ6J/src/events.jl:85
└ @ WGLMakie ~/.julia/packages/WGLMakie/7QQ6J/src/events.jl:112
SimonDanisch commented 1 month ago

@ffreyer for me things start going wrong at:

julia> ax.finallimits[]
GeometryBasics.HyperRectangle{2, Float64}([1.999999999999921, 1.9999999999997584], [1.4251023369176903e-13, 4.0290822310126116e-13])

I guess that's even for Float64 too far? I'd say we should just disallow zooming this far? Would be nice to have upper/lower zoom limits anyways!

ffreyer commented 1 month ago

Seems a little early with eps(Float64) ~ 1e-16 but yea, it's still going to happen eventually.