From 791ff1d82d1f8693d2b6db1257f0f0776bc51e8d Mon Sep 17 00:00:00 2001
From: Daniel Vedder <daniel.vedder@idiv.de>
Date: Thu, 26 Oct 2023 12:36:55 +0200
Subject: [PATCH] Refactored makieplots.jl

---
 Project.toml               |  2 +-
 src/analysis/makieplots.jl | 43 +++++++++++++++++++++++++-------------
 src/core/output.jl         |  2 +-
 3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/Project.toml b/Project.toml
index f873077..bd97680 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,7 +1,7 @@
 name = "Persefone"
 uuid = "039acd1d-2a07-4b33-b082-83a1ff0fd136"
 authors = ["Daniel Vedder <daniel.vedder@idiv.de>"]
-version = "0.3.5"
+version = "0.3.6"
 
 [deps]
 Agents = "46ada45e-f475-11e8-01d0-f70cc89e6671"
diff --git a/src/analysis/makieplots.jl b/src/analysis/makieplots.jl
index 23b85cd..1167b0d 100644
--- a/src/analysis/makieplots.jl
+++ b/src/analysis/makieplots.jl
@@ -28,14 +28,16 @@ function visualisemap(model::AgentBasedModel,date=nothing,landcover=nothing)
         return f
     end
     isnothing(date) && (date = inds.Date[end])
-    update_theme!(palette=(color=cgrad(:seaborn_bright, length(unique(inds.Species))),),
+    update_theme!(palette=(color=cgrad(:seaborn_bright,
+                                       length(@param(nature.targetspecies))),),
                   cycle=[:color])
-    for s in unique(inds.Species)
+    for s in @param(nature.targetspecies)
         points = @select!(@subset(inds, :Species .== s, :Date .== date),
                           :X, :Y)
+        iszero(size(points)[1]) && continue
         # The origin in Makie is in the bottom-left rather than in the top-left as
         # on the model map, so we have to invert the Y coordinates
-        @transform!(points, :Y = size(model.landscape)[2] .- :Y)
+        @transform!(points, :Y = size(landcover)[2] .- :Y)
         scatter!(f[1,1], Matrix{Float32}(points), markersize=8)
     end
     f
@@ -50,7 +52,28 @@ Returns a Makie figure object.
 function populationtrends(model::AgentBasedModel)
     pops = model.datatables["populations"]
     # create the labels needed for the ticks on the X axis
+    update_theme!(palette=(color=cgrad(:seaborn_bright, length(unique(pops.Species))),),
+                  cycle=[:color])
+    f = Figure()
     dates = @param(core.startdate):@param(core.enddate)
+    ax = Axis(f[1,1], xlabel="Date", ylabel="Population size",
+              limits=((1, length(dates)), nothing), xticks = gettickmarks(dates))
+    for s in @param(nature.targetspecies)
+        points = @select!(@subset(pops, :Species .== s), :Abundance)
+        iszero(size(points)[1]) && continue
+        lines!(f[1,1], Vector{Float32}(points.Abundance), linewidth=3, label=s)
+    end
+    size(pops)[1] > 0 && axislegend("Species"; position=:lt)
+    f
+end
+
+"""
+    gettickmarks(dates)
+
+Given a vector of dates, construct a selection to use as tick mark locations.
+Helper function for `[populationtrends](@ref)`
+"""
+function gettickmarks(dates)
     ticks = (Int[], String[])
     for i in 1:length(dates)
         if Day(dates[i]) == Day(1)
@@ -62,15 +85,7 @@ function populationtrends(model::AgentBasedModel)
         deleteat!(ticks[1], 2:2:length(ticks[1]))
         deleteat!(ticks[2], 2:2:length(ticks[2]))            
     end
-    update_theme!(palette=(color=cgrad(:seaborn_bright, length(unique(pops.Species))),),
-                  cycle=[:color])
-    f = Figure()
-    ax = Axis(f[1,1], xlabel="Date", ylabel="Population size",
-              limits=((1, length(dates)), nothing), xticks = ticks)
-    for s in unique(pops.Species)
-        points = @select!(@subset(pops, :Species .== s), :Abundance)
-        lines!(f[1,1], Vector{Float32}(points.Abundance), linewidth=3, label=s)
-    end
-    size(pops)[1] > 0 && axislegend("Species"; position=:lt)
-    f
+    ticks
 end
+
+#XXX add animation with record()? https://docs.makie.org/stable/explanations/animation/
diff --git a/src/core/output.jl b/src/core/output.jl
index f6599f2..98b5b42 100644
--- a/src/core/output.jl
+++ b/src/core/output.jl
@@ -217,7 +217,7 @@ saving each figure as a PDF.
 """
 function visualiseoutput(model::AgentBasedModel, format::String="pdf")
     @debug "Visualising output."
-    CairoMakie.activate!()
+    CairoMakie.activate!() # make sure we're using Cairo
     for output in model.dataoutputs
         isnothing(output.plotfunction) && continue
         figure = output.plotfunction(model)
-- 
GitLab