Agents.jl
Agents.jl copied to clipboard
Fix hover inspection for abstract spaces
Currently there's a bug in Agents where trying to hover inspect a 2D continuous plot throws a DimensionMismatch error. This seems analogous to #1090 , fixed in #1092 .
You can reproduce the bug by doing something like:
using Agents
using GLMakie
using AgentsExampleZoo
model = AgentsExampleZoo.flocking()
fig, abmobs = abmexploration(model)
fig
And trying to hover over any agent. You'll get an error like:
nested task error: DimensionMismatch: arrays could not be broadcast to a common size
Stacktrace:
[1] _bcs1(a::StaticArrays.SOneTo{2}, b::StaticArrays.SOneTo{3})
@ StaticArrays ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:77
[2] _bcs(shape::Tuple{StaticArrays.SOneTo{2}}, newshape::Tuple{StaticArrays.SOneTo{3}})
@ Base.Broadcast ./broadcast.jl:522
[3] broadcast_shape(::Tuple{StaticArrays.SOneTo{2}}, ::Tuple{StaticArrays.SOneTo{3}})
@ Base.Broadcast ./broadcast.jl:516
[4] static_combine_axes
@ ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:20 [inlined]
[5] _axes(bc::Base.Broadcast.Broadcasted{StaticArraysCore.StaticArrayStyle{1}, Nothing, typeof(-), Tuple{SVector{2, Float64}, Tuple{Float64, Float64, Float64}}}, ::Nothing)
@ StaticArrays ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:25
[6] axes
@ ./broadcast.jl:234 [inlined]
[7] static_axes(A::Base.Broadcast.Broadcasted{StaticArraysCore.StaticArrayStyle{1}, Nothing, typeof(-), Tuple{SVector{2, Float64}, Tuple{Float64, Float64, Float64}}})
@ StaticArrays ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:22
[8] static_combine_axes(A::Base.Broadcast.Broadcasted{StaticArraysCore.StaticArrayStyle{1}, Nothing, typeof(-), Tuple{SVector{2, Float64}, Tuple{Float64, Float64, Float64}}})
@ StaticArrays ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:21
[9] static_combine_axes
@ ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:20 [inlined]
[10] _axes(bc::Base.Broadcast.Broadcasted{StaticArraysCore.StaticArrayStyle{1}, Nothing, typeof(min), Tuple{Tuple{Float64, Float64, Float64}, Base.Broadcast.Broadcasted{StaticArraysCore.StaticArrayStyle{1}, Nothing, typeof(-), Tuple{SVector{2, Float64}, Tuple{Float64, Float64, Float64}}}}}, ::Nothing)
@ StaticArrays ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:25
[11] axes
@ ./broadcast.jl:234 [inlined]
[12] static_axes(A::Base.Broadcast.Broadcasted{StaticArraysCore.StaticArrayStyle{1}, Nothing, typeof(min), Tuple{Tuple{Float64, Float64, Float64}, Base.Broadcast.Broadcasted{StaticArraysCore.StaticArrayStyle{1}, Nothing, typeof(-), Tuple{SVector{2, Float64}, Tuple{Float64, Float64, Float64}}}}})
@ StaticArrays ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:22
[13] static_combine_axes (repeats 2 times)
@ ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:20 [inlined]
[14] instantiate
@ ~/.julia/packages/StaticArrays/LSPcF/src/broadcast.jl:32 [inlined]
[15] materialize
@ ./broadcast.jl:872 [inlined]
[16] euclidean_distance(p1::Tuple{Float64, Float64, Float64}, p2::Tuple{Float64, Float64, Float64}, space::ContinuousSpace{2, true, Float64, typeof(Agents.no_vel_update)})
@ Agents ~/.julia/dev/Agents/src/spaces/utilities.jl:42
[17] euclidean_distance(p1::Tuple{Float64, Float64, Float64}, p2::Tuple{Float64, Float64, Float64}, model::StandardABM{ContinuousSpace{2, true, Float64, typeof(Agents.no_vel_update)}, AgentsExampleZoo.Bird, Vector{AgentsExampleZoo.Bird}, Tuple{DataType}, typeof(AgentsExampleZoo.flocking_agent_step!), typeof(dummystep), Agents.Schedulers.Randomly, Nothing, TaskLocalRNG})
@ Agents ~/.julia/dev/Agents/src/spaces/utilities.jl:26
[18] distance_from_cell_center(pos::Tuple{Float64, Float64, Float64}, model::StandardABM{ContinuousSpace{2, true, Float64, typeof(Agents.no_vel_update)}, AgentsExampleZoo.Bird, Vector{AgentsExampleZoo.Bird}, Tuple{DataType}, typeof(AgentsExampleZoo.flocking_agent_step!), typeof(dummystep), Agents.Schedulers.Randomly, Nothing, TaskLocalRNG})
@ Agents ~/.julia/dev/Agents/src/spaces/continuous.jl:119
[19] nearby_ids_approx(pos::Tuple{Float64, Float64, Float64}, model::StandardABM{ContinuousSpace{2, true, Float64, typeof(Agents.no_vel_update)}, AgentsExampleZoo.Bird, Vector{AgentsExampleZoo.Bird}, Tuple{DataType}, typeof(AgentsExampleZoo.flocking_agent_step!), typeof(dummystep), Agents.Schedulers.Randomly, Nothing, TaskLocalRNG}, r::Float64)
@ Agents ~/.julia/dev/Agents/src/spaces/continuous.jl:217
[20] nearby_ids_exact(pos::Tuple{Float64, Float64, Float64}, model::StandardABM{ContinuousSpace{2, true, Float64, typeof(Agents.no_vel_update)}, AgentsExampleZoo.Bird, Vector{AgentsExampleZoo.Bird}, Tuple{DataType}, typeof(AgentsExampleZoo.flocking_agent_step!), typeof(dummystep), Agents.Schedulers.Randomly, Nothing, TaskLocalRNG}, r::Float64)
@ Agents ~/.julia/dev/Agents/src/spaces/continuous.jl:231
[21] ids_to_inspect(model::StandardABM{ContinuousSpace{2, true, Float64, typeof(Agents.no_vel_update)}, AgentsExampleZoo.Bird, Vector{AgentsExampleZoo.Bird}, Tuple{DataType}, typeof(AgentsExampleZoo.flocking_agent_step!), typeof(dummystep), Agents.Schedulers.Randomly, Nothing, TaskLocalRNG}, pos::Tuple{Float64, Float64, Float64})
@ AgentsVisualizations ~/.julia/dev/Agents/ext/AgentsVisualizations/src/spaces/continuous.jl:43
[22] agent2string(model::StandardABM{ContinuousSpace{2, true, Float64, typeof(Agents.no_vel_update)}, AgentsExampleZoo.Bird, Vector{AgentsExampleZoo.Bird}, Tuple{DataType}, typeof(AgentsExampleZoo.flocking_agent_step!), typeof(dummystep), Agents.Schedulers.Randomly, Nothing, TaskLocalRNG}, pos::Tuple{Float64, Float64, Float64})
@ AgentsVisualizations ~/.julia/dev/Agents/ext/AgentsVisualizations/src/spaces/abstract.jl:143
[23] show_data(inspector::DataInspector, p::Plot{AgentsVisualizations._abmplot, Tuple{ABMObservable{Observable{StandardABM{ContinuousSpace{2, true, Float64, typeof(Agents.no_vel_update)}, AgentsExampleZoo.Bird, Vector{AgentsExampleZoo.Bird}, Tuple{DataType}, typeof(AgentsExampleZoo.flocking_agent_step!), typeof(dummystep), Agents.Schedulers.Randomly, Nothing, TaskLocalRNG}}, Nothing, Nothing, Nothing, Nothing, Bool, Observable{Int64}, Observable{Tuple{Base.RefValue{Int64}, Vector{Int64}}}}}}, idx::UInt32, source::Scatter{Tuple{Vector{Point{2, Float32}}}})
@ AgentsVisualizations ~/.julia/dev/Agents/ext/AgentsVisualizations/src/spaces/abstract.jl:101
[24] show_data_recursion(inspector::DataInspector, plot::Plot{AgentsVisualizations._abmplot, Tuple{ABMObservable{Observable{StandardABM{ContinuousSpace{2, true, Float64, typeof(Agents.no_vel_update)}, AgentsExampleZoo.Bird, Vector{AgentsExampleZoo.Bird}, Tuple{DataType}, typeof(AgentsExampleZoo.flocking_agent_step!), typeof(dummystep), Agents.Schedulers.Randomly, Nothing, TaskLocalRNG}}, Nothing, Nothing, Nothing, Nothing, Bool, Observable{Int64}, Observable{Tuple{Base.RefValue{Int64}, Vector{Int64}}}}}}, idx::UInt32, source::Scatter{Tuple{Vector{Point{2, Float32}}}})
@ Makie ~/.julia/packages/Makie/6KcTF/src/interaction/inspector.jl:373
[25] show_data_recursion(inspector::DataInspector, plot::Scatter{Tuple{Vector{Point{2, Float32}}}}, idx::UInt32)
@ Makie ~/.julia/packages/Makie/6KcTF/src/interaction/inspector.jl:343
[26] on_hover(inspector::DataInspector)
@ Makie ~/.julia/packages/Makie/6KcTF/src/interaction/inspector.jl:326
[27] (::Makie.var"#1338#1342"{Scene, DataInspector})(ch::Channel{Nothing})
@ Makie ~/.julia/packages/Makie/6KcTF/src/interaction/inspector.jl:291
[28] (::Base.var"#739#740"{Makie.var"#1338#1342"{Scene, DataInspector}, Channel{Nothing}})()
@ Base ./channels.jl:142
Error in callback:
TaskFailedException
Stacktrace:
[1] check_channel_state
@ ./channels.jl:188 [inlined]
[2] put!
@ ./channels.jl:356 [inlined]
[3] (::Makie.var"#1339#1343"{Channel{Nothing}})(::Tuple{Float64, Float64}, ::Tuple{Float64, Float64})
@ Makie ~/.julia/packages/Makie/6KcTF/src/interaction/inspector.jl:301
[4] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
@ Base ./essentials.jl:1055
[5] invokelatest(::Any, ::Any, ::Vararg{Any})
@ Base ./essentials.jl:1052
[6] (::Observables.OnAny)(value::Any)
@ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:420
[7] #invokelatest#2
@ ./essentials.jl:1055 [inlined]
[8] invokelatest
@ ./essentials.jl:1052 [inlined]
[9] notify
@ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
[10] setindex!(observable::Observable, val::Any)
@ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
[11] (::GLMakie.MousePositionUpdater)(::Makie.TickState)
@ GLMakie ~/.julia/packages/GLMakie/YAome/src/events.jl:6
[12] #invokelatest#2
@ ./essentials.jl:1055 [inlined]
[13] invokelatest
@ ./essentials.jl:1052 [inlined]
[14] notify
@ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
[15] setindex!
@ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123 [inlined]
[16] pollevents(screen::GLMakie.Screen{GLFW.Window}, frame_state::Makie.TickState)
@ GLMakie ~/.julia/packages/GLMakie/YAome/src/screen.jl:547
[17] on_demand_renderloop(screen::GLMakie.Screen{GLFW.Window})
@ GLMakie ~/.julia/packages/GLMakie/YAome/src/screen.jl:1038
[18] renderloop(screen::GLMakie.Screen{GLFW.Window})
@ GLMakie ~/.julia/packages/GLMakie/YAome/src/screen.jl:1066
[19] (::GLMakie.var"#79#80"{GLMakie.Screen{GLFW.Window}})()
@ GLMakie ~/.julia/packages/GLMakie/YAome/src/screen.jl:927
This pull request fixes that.
Codecov Report
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 85.23%. Comparing base (
8b5b456) to head (b042605). Report is 187 commits behind head on main.
Additional details and impacted files
@@ Coverage Diff @@
## main #1159 +/- ##
===========================================
+ Coverage 70.12% 85.23% +15.10%
===========================================
Files 42 38 -4
Lines 2718 2614 -104
===========================================
+ Hits 1906 2228 +322
+ Misses 812 386 -426
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
@hbsmith can you put a note in the dev docs and then we merge this? or is anything else missing?
It's not clear to me what you want me to write or where exactly in the dev docs you want it to go. If you tell me what you want exactly, I can add it.
I don't understand the error and how this PR solves it. The positions in the flocking model are 2D. If you make a tuple out of them it is still 2D. What is the point if accessing them with 1:length(...)? Which is also a very expensive operation, we need to find a more performant way to do this.
if I remember correctly the problem is that pos contains some more dimensions than what you would expect for some reason. So I trust that this commit fixes the problem. I would specialize the function for ContinuousSpace though for safety.