Skip to content
This repository has been archived by the owner on Jun 21, 2024. It is now read-only.

Actually fix agents docpage #102

Merged
merged 5 commits into from
Jul 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "InteractiveDynamics"
uuid = "ec714cd0-5f51-11eb-0b6e-452e7367ff84"
repo = "https://github.com/JuliaDynamics/InteractiveDynamics.jl.git"
version = "0.21.6"
version = "0.21.7"

[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Expand Down
18 changes: 11 additions & 7 deletions docs/src/agents.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@

# This page describes functions that can be used in conjunction with
# [Agents.jl](https://juliadynamics.github.io/Agents.jl/dev/) to animate and interact
# with agent based models.
# with agent based models.

# The animation at the start of the page is created using the code of this page, see below.

# The docs are built using versions:
using Pkg
Pkg.status(["Agents", "InteractiveDynamics"];
Pkg.status(["Agents", "InteractiveDynamics", "CairoMakie"];
mode = PKGMODE_MANIFEST, io=stdout
)

Expand All @@ -28,13 +28,15 @@ using InteractiveDynamics, Agents
using CairoMakie
daisypath = joinpath(dirname(pathof(InteractiveDynamics)), "agents", "daisyworld_def.jl")
include(daisypath)
model, daisy_step!, daisyworld_step! = daisyworld(; solar_luminosity = 1.0, solar_change = 0.0, scenario = :change)
model, daisy_step!, daisyworld_step! = daisyworld(;
solar_luminosity = 1.0, solar_change = 0.0, scenario = :change
)
model

# Now, to plot daisyworld is as simple as
daisycolor(a::Daisy) = a.breed # color of agents
as = 14 # size of agents
am = '' # marker of agents
as = 20 # size of agents
am = '' # marker of agents
scatterkwargs = (strokewidth = 1.0,) # add stroke around each agent
fig, ax, abmobs = abmplot(model; ac = daisycolor, as, am, scatterkwargs)
fig
Expand Down Expand Up @@ -64,7 +66,8 @@ fig
# Note that [`GLMakie`](https://makie.juliaplots.org/v0.15/documentation/backends_and_output/)
# should be used instead of `CairoMakie` when wanting to use the interactive
# aspects of the plots.
fig, ax, abmobs = abmplot(model; agent_step! = daisy_step!, model_step! = daisyworld_step!,
fig, ax, abmobs = abmplot(model;
agent_step! = daisy_step!, model_step! = daisyworld_step!,
plotkwargs...)
fig

Expand All @@ -74,7 +77,8 @@ params = Dict(
:surface_albedo => 0:0.01:1,
:solar_change => -0.1:0.01:0.1,
)
fig, ax, abmobs = abmplot(model; agent_step! = daisy_step!, model_step! = daisyworld_step!,
fig, ax, abmobs = abmplot(model;
agent_step! = daisy_step!, model_step! = daisyworld_step!,
params, plotkwargs...)
fig

Expand Down
2 changes: 1 addition & 1 deletion src/agents/abmplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,11 @@ function Makie.plot!(abmplot::_ABMPlot)
hmap = heatmap!(abmplot, heatobs; colormap = JULIADYNAMICS_CMAP, abmplot.heatkwargs...)
if abmplot.add_colorbar[]
Colorbar(fig[1, 1][1, 2], hmap, width = 20)
rowsize!(fig[1, 1].layout, 1, ax.scene.px_area[].widths[2])
# TODO: Set colorbar to be "glued" to axis
# Problem with the following code, which comes from the tutorial
# https://makie.juliaplots.org/stable/tutorials/aspect-tutorial/ ,
# is that it only works for axis that have 1:1 aspect ratio...
# rowsize!(fig[1, 1].layout, 1, ax.scene.px_area[].widths[2])
# colsize!(fig[1, 1].layout, 1, Aspect(1, 1.0))
end
end
Expand Down
16 changes: 8 additions & 8 deletions src/agents/convenience.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ The plotting is identical as in [`abmplot`](@ref) and applicable keywords are pr
* `kwargs...`: All other keywords are propagated to [`abmplot`](@ref).
"""
function abmvideo(file, model, agent_step!, model_step! = Agents.dummystep;
spf = 1, framerate = 30, frames = 300, title = "", showstep = true,
figure = NamedTuple(), axis = NamedTuple(), kwargs...)
spf = 1, framerate = 30, frames = 300, title = "", showstep = true,
figure = (resolution = (600, 600),), axis = NamedTuple(), kwargs...
)
# add some title stuff
s = Observable(0) # counter of current step
if title ≠ "" && showstep
Expand All @@ -135,16 +136,15 @@ function abmvideo(file, model, agent_step!, model_step! = Agents.dummystep;
end
axis = (title = t, titlealign = :left, axis...)

fig = Figure(; resolution = (600,600), backgroundcolor = DEFAULT_BG, figure...)
ax = fig[1,1][1,1] = agents_space_dimensionality(model) == 3 ?
Axis3(fig; axis...) : Axis(fig; axis...)
p = abmplot!(ax, model; kwargs...)
fig, ax, abmobs = abmplot(model;
add_controls = false, agent_step!, model_step!, figure, axis, kwargs...)

resize_to_layout!(fig)

record(fig, file; framerate) do io
for j in 1:frames-1
recordframe!(io)
Agents.step!(model, agent_step!, model_step!, spf)
p.model[] = model
Agents.step!(abmobs, spf)
s[] += spf; s[] = s[]
end
recordframe!(io)
Expand Down
11 changes: 6 additions & 5 deletions src/agents/daisyworld_def.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ function daisyworld_step!(model)
diffuse_temperature!(p, model)
propagate!(p, model)
end
model.tick[] = model.tick[] + 1
model.tick = model.tick + 1
solar_activity!(model)
end

function solar_activity!(model::DaisyWorld)
if model.scenario == :ramp
if model.tick[] > 200 && model.tick[] ≤ 400
if model.tick > 200 && model.tick ≤ 400
model.solar_luminosity += model.solar_change
end
if model.tick[] > 500 && model.tick[] ≤ 750
if model.tick > 500 && model.tick ≤ 750
model.solar_luminosity -= model.solar_change / 2
end
elseif model.scenario == :change
Expand All @@ -95,8 +95,9 @@ function daisyworld(;
rng = MersenneTwister(seed)
space = GridSpaceSingle(griddims)
properties = (;max_age, surface_albedo, solar_luminosity, solar_change, scenario,
tick = Ref(0), ratio = 0.5, temperature = zeros(griddims)
tick = 0, ratio = 0.5, temperature = zeros(griddims)
)
properties = Dict(k=>v for (k,v) in pairs(properties))

model = ABM(Daisy, space; properties, rng)

Expand All @@ -120,5 +121,5 @@ function daisyworld(;
update_surface_temperature!(p, model)
end

return model
return model, daisy_step!, daisyworld_step!
end
14 changes: 8 additions & 6 deletions src/agents/interaction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,21 @@ end
function add_param_sliders!(fig, model, params, resetclick)
datalayout = fig[end,:][1,2] = GridLayout(tellheight = true)

# TODO: This needs to become `SliderGrid`.
slidervals = Dict{Symbol, Observable}()
tuples_for_slidergrid = []
for (i, (k, vals)) in enumerate(params)
startvalue = has_key(model[].properties, k) ?
get_value(model[].properties, k) : vals[1]
sll = labelslider!(fig, string(k), vals; sliderkw = Dict(:startvalue => startvalue))
slidervals[k] = sll.slider.value # directly add the observable
datalayout[i, :] = sll.layout
label = string(k)
push!(tuples_for_slidergrid, (;label, range = vals, startvalue))
end
sg = SliderGrid(datalayout[1,1], tuples_for_slidergrid...; tellheight = true)
for (i, (l, vals)) in enumerate(params)
slidervals[l] = sg.sliders[i].value
end

# Update button
update = Button(fig, label = "update")
update = Button(datalayout[end+1, :], label = "update", tellwidth = false)
on(update.clicks) do c
for (k, v) in pairs(slidervals)
if has_key(model[].properties, k)
Expand All @@ -128,7 +131,6 @@ function add_param_sliders!(fig, model, params, resetclick)
end
end
end
datalayout[end+1, :] = MakieLayout.hbox!(update; tellwidth = false)
# Ensure resetted model has new parameters
on(resetclick) do c
update.clicks[] = update.clicks[] + 1
Expand Down