diff --git a/examples/agents_visualizations.jl b/examples/agents_visualizations.jl index 08d737831a..0ff0b14c95 100644 --- a/examples/agents_visualizations.jl +++ b/examples/agents_visualizations.jl @@ -48,10 +48,10 @@ model # for the agents that depend on the agent properties, and # a size and marker style that are constants, daisycolor(a) = a.breed # agent color -agent_size = 20 -agent_marker = '✿' +agent_size = 20 # agent size +agent_marker = '✿' # agent marker agentsplotkwargs = (strokewidth = 1.0,) # add stroke around each agent -fig, ax, abmobs = abmplot(model; ac = daisycolor, as, am, agentsplotkwargs) +fig, ax, abmobs = abmplot(model; agent_color = daisycolor, agent_size, agent_marker, agentsplotkwargs) fig # !!! note "Supported keyword arguments" @@ -283,5 +283,5 @@ agentsplotkwargs = ( edge_plottype = :linesegments # needed for tapered edge widths ) -fig, ax, abmobs = abmplot(sir_model; agent_size = city_size, ac = city_color, agentsplotkwargs) +fig, ax, abmobs = abmplot(sir_model; agent_size = city_size, agent_color = city_color, agentsplotkwargs) fig diff --git a/ext/AgentsVisualizations/src/convenience.jl b/ext/AgentsVisualizations/src/convenience.jl index 728409b5cc..a29cd59a34 100644 --- a/ext/AgentsVisualizations/src/convenience.jl +++ b/ext/AgentsVisualizations/src/convenience.jl @@ -67,8 +67,9 @@ function init_abm_data_plots!(fig, abmobs, adata, mdata, alabels, mlabels, plotk end end on(resetclick) do clicks + for ax in axs - vlines!(ax, [abmtime(abmobs.model[])], color = "#c41818") + vlines!(ax, [abmobs._offset_time[]], color = "#c41818") end end return nothing diff --git a/ext/AgentsVisualizations/src/interaction.jl b/ext/AgentsVisualizations/src/interaction.jl index 0b8608c136..e237d6128f 100644 --- a/ext/AgentsVisualizations/src/interaction.jl +++ b/ext/AgentsVisualizations/src/interaction.jl @@ -22,7 +22,7 @@ function add_controls!(fig, abmobs, spu) getfield.(Ref(abmobs), (:model, :agent_step!, :model_step!, :adata, :mdata, :adf, :mdf, :when)) init_dataframes!(model[], adata, mdata, adf, mdf) - collect_data!(model[], when, adata, mdata, adf, mdf) + collect_data!(abmobs, model[], when, adata, mdata, adf, mdf) # Create new layout for control buttons controllayout = fig[end+1,:][1,1] = GridLayout(tellheight = true) @@ -42,7 +42,7 @@ function add_controls!(fig, abmobs, spu) step = Button(fig, label = "step\nmodel") on(step.clicks) do c Agents.step!(abmobs, speed[]) - collect_data!(model[], when[], adata, mdata, adf, mdf) + collect_data!(abmobs, model[], when[], adata, mdata, adf, mdf) end # Run button run = Button(fig, label = "run\nmodel") @@ -63,13 +63,14 @@ function add_controls!(fig, abmobs, spu) reset = Button(fig, label = "reset\nmodel") model0 = deepcopy(model[]) # backup initial model state on(reset.clicks) do c + abmobs._offset_time[] += abmtime(model[]) model[] = deepcopy(model0) end # Clear button clear = Button(fig, label = "clear\ndata") on(clear.clicks) do c init_dataframes!(model[], adata, mdata, adf, mdf) - collect_data!(model[], when, adata, mdata, adf, mdf) + collect_data!(abmobs, model[], when, adata, mdata, adf, mdf) end # Layout buttons controllayout[2, :] = Makie.hbox!(step, run, reset, clear; tellwidth = false) @@ -88,14 +89,14 @@ function init_dataframes!(model, adata, mdata, adf, mdf) return nothing end -function collect_data!(model, when, adata, mdata, adf, mdf) +function collect_data!(abmobs, model, when, adata, mdata, adf, mdf) if Agents.should_we_collect(abmtime(model), model, when) if !isnothing(adata) - Agents.collect_agent_data!(adf[], model, adata) + Agents.collect_agent_data!(adf[], model, adata; _offset_time=abmobs._offset_time[]) adf[] = adf[] # trigger Observable end if !isnothing(mdata) - Agents.collect_model_data!(mdf[], model, mdata) + Agents.collect_model_data!(mdf[], model, mdata; _offset_time=abmobs._offset_time[]) mdf[] = mdf[] # trigger Observable end end diff --git a/ext/AgentsVisualizations/src/model_observable.jl b/ext/AgentsVisualizations/src/model_observable.jl index 13b03a99e3..ae0b6e5a37 100644 --- a/ext/AgentsVisualizations/src/model_observable.jl +++ b/ext/AgentsVisualizations/src/model_observable.jl @@ -17,12 +17,12 @@ function Agents.ABMObservable(model::AgentBasedModel; mdf = Observable(Agents.init_model_dataframe(model, mdata)) end return ABMObservable( - Observable(model), agent_step!, model_step!, adata, mdata, adf, mdf, Observable(0), when - ) + Observable(model), agent_step!, model_step!, adata, mdata, adf, mdf, Observable(0), when) end function Agents.step!(abmobs::ABMObservable, n; kwargs...) model, adf, mdf = abmobs.model, abmobs.adf, abmobs.mdf + abmobs._offset_time[] += n if Agents.agent_step_field(model[]) != Agents.dummystep || Agents.model_step_field(model[]) != Agents.dummystep Agents.step!(model[], n; kwargs...) else @@ -31,11 +31,11 @@ function Agents.step!(abmobs::ABMObservable, n; kwargs...) notify(model) if Agents.should_we_collect(abmtime(model[]), model[], abmobs.when) if !isnothing(abmobs.adata) - Agents.collect_agent_data!(adf[], model[], abmobs.adata) + Agents.collect_agent_data!(adf[], model[], abmobs.adata; _offset_time=abmobs._offset_time[]) notify(adf) end if !isnothing(abmobs.mdata) - Agents.collect_model_data!(mdf[], model[], abmobs.mdata) + Agents.collect_model_data!(mdf[], model[], abmobs.mdata; _offset_time=abmobs._offset_time[]) notify(mdf) end end @@ -48,4 +48,4 @@ function Base.show(io::IO, abmobs::ABMObservable) print(io, "\nand with data collection:\n") print(io, " adata: $(abmobs.adata)\n") print(io, " mdata: $(abmobs.mdata)") -end \ No newline at end of file +end diff --git a/ext/AgentsVisualizations/src/spaces/abstract.jl b/ext/AgentsVisualizations/src/spaces/abstract.jl index b1cbfba3ca..09df9f6ba5 100644 --- a/ext/AgentsVisualizations/src/spaces/abstract.jl +++ b/ext/AgentsVisualizations/src/spaces/abstract.jl @@ -1,9 +1,8 @@ Agents.agents_space_dimensionality(model::ABM) = Agents.agents_space_dimensionality(abmspace(model)) -"Plot agents into a 2D space." function Agents.agentsplot!(ax::Axis, p::ABMP) - if user_used_polygons(p.am[], p.marker[]) + if user_used_polygons(p.agent_marker[], p.marker[]) poly!(p, p.marker; p.color, p.marker, p.markersize, p.agentsplotkwargs...) else scatter!(p, p.pos; p.color, p.marker, p.markersize, p.agentsplotkwargs...) @@ -13,8 +12,8 @@ end "Plot agents into a 3D space." function Agents.agentsplot!(ax::Axis3, p::_ABMPlot) - if p.am[] === :circle - p.am[], p.marker[] = :Sphere, Sphere(Point3f(0), 1) + if p.agent_marker[] === :circle + p.agent_marker[], p.marker[] = :Sphere, Sphere(Point3f(0), 1) end meshscatter!(p, p.pos; p.color, p.marker, p.markersize, p.agentsplotkwargs...) return p diff --git a/src/simulations/collect.jl b/src/simulations/collect.jl index 3dda286fad..916e3481b5 100644 --- a/src/simulations/collect.jl +++ b/src/simulations/collect.jl @@ -547,14 +547,14 @@ Collect and add agent data into `df` (see [`run!`](@ref) for the dispatch rules of `properties` and `obtainer`). """ collect_agent_data!(df, model, properties::Nothing, step::Int = 0; kwargs...) = df -function collect_agent_data!(df, model, properties::Vector, step::Int = 0; kwargs...) +function collect_agent_data!(df, model, properties::Vector, step::Int = 0; _offset_time = 0, kwargs...) if step != 0 @warn "Passing the `step` argument to `collect_agent_data!` is deprecated, now `abmtime(model)` is used automatically" maxlog=1 end alla = sort!(collect(allagents(model)), by = a -> a.id) dd = DataFrame() - dd[!, :step] = fill(abmtime(model), length(alla)) + dd[!, :step] = fill(abmtime(model)+_offset_time, length(alla)) dd[!, :id] = map(a -> a.id, alla) if :agent_type ∈ propertynames(df) dd[!, :agent_type] = map(a -> Symbol(typeof(a)), alla) @@ -571,6 +571,7 @@ function collect_agent_data!( model::ABM, properties::Vector{<:Tuple}, step::Int = 0; + _offset_time = 0, kwargs..., ) if step != 0 @@ -578,7 +579,7 @@ function collect_agent_data!( now `abmtime(model)` is used automatically" maxlog=1 end alla = allagents(model) - push!(df[!, 1], abmtime(model)) + push!(df[!, 1], abmtime(model)+_offset_time) for (i, prop) in enumerate(properties) _add_col_data!(df[!, i+1], prop, alla; kwargs...) end @@ -595,13 +596,14 @@ function collect_model_data!( model, properties::Vector, step::Real = 0; + _offset_time = 0, obtainer = identity, ) if step != 0 @warn "Passing the `step` argument to `collect_model_data!` is deprecated, now `abmtime(model)` is used automatically" maxlog=1 end - push!(df[!, :step], abmtime(model)) + push!(df[!, :step], abmtime(model)+_offset_time) for fn in properties push!(df[!, dataname(fn)], get_data(model, fn, obtainer)) end diff --git a/src/visualizations.jl b/src/visualizations.jl index 4046189e48..3613bd0f94 100644 --- a/src/visualizations.jl +++ b/src/visualizations.jl @@ -158,7 +158,7 @@ struct ABMObservable{M, AS, MS, AD, MD, ADF, MDF, W, S} mdata::MD adf::ADF # this is `nothing` or `Observable` mdf::MDF # this is `nothing` or `Observable` - s::S # Observable{Int} + _offset_time::S # Observable{Int} when::W end export ABMObservable