From 6b59a26e5a2757b315f0ee07b6e0dadb6e990ffa Mon Sep 17 00:00:00 2001
From: Daniel Vedder <daniel.vedder@idiv.de>
Date: Thu, 5 Oct 2023 17:53:29 +0200
Subject: [PATCH] Started working on results visualisation with Makie.

Unfortunately, including Makie as a dependency increases the compile
time to ~5 minutes. This is unacceptable and I need to find a fix for
it, if possible.
---
 src/analysis/makieplots.jl   | 45 ++++++++++++++++++++++++++++++++++++
 src/nature/ecologicaldata.jl | 13 ++++++-----
 2 files changed, 52 insertions(+), 6 deletions(-)
 create mode 100644 src/analysis/makieplots.jl

diff --git a/src/analysis/makieplots.jl b/src/analysis/makieplots.jl
new file mode 100644
index 0000000..00e871d
--- /dev/null
+++ b/src/analysis/makieplots.jl
@@ -0,0 +1,45 @@
+### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
+###
+### This file visualises model output using Makie.
+###
+
+"""
+    visualisemap(model, date)
+
+Draw the model's land cover map and plot all individuals as points on it at the
+specified date. If no date is passed, use the last date for which data are available.
+Returns a Makie figure object.
+"""
+function visualisemap(model::AgentBasedModel, date::Union{Date,Nothing}=nothing)
+    # extract the data from the model and load the map
+    inds = model.datatables["individuals"]
+    isnothing(date) && (date = inds.Date[end])
+    landcover = load(@param(world.landcovermap))
+    # draw the map
+    f = Figure()
+    ax = Axis(f[1,1])
+    hidedecorations!(ax)
+    image!(f[1,1], rotr90(landcover))
+    ax.aspect = DataAspect()
+    # plot individuals
+    for s in unique(inds.Species)
+        points = @select!(@subset(inds, :Species .== s, :Date .== date), :X, :Y)
+        scatter!(f[1,1], Matrix{Float32}(points), markersize=10)
+    end
+    f
+end
+
+"""
+    populationtrends(model)
+
+Plot a line graph of population sizes of each species over time.
+Returns a Makie figure object.
+"""
+function populationtrends(model::AgentBasedModel)
+    pops = model.datatables["populations"]
+    f = Figure()
+    for s in unique(inds.Species)
+        points = @select!(@subset(pops, :Species .== s), :X, :Y)
+        lines!(f[1,1], Matrix{Float32}(points), markersize=10)
+    end
+end
diff --git a/src/nature/ecologicaldata.jl b/src/nature/ecologicaldata.jl
index 445fc7c..5f65954 100644
--- a/src/nature/ecologicaldata.jl
+++ b/src/nature/ecologicaldata.jl
@@ -3,8 +3,9 @@
 ### This file includes the functions for collecting and saving ecological output data.
 ###
 
-const POPTABLE = "populations"
-const INDDATA = "individuals"
+#XXX NOP functions while I try and get Makie to work
+visualisemap(model) = nothing
+populationtrends(model) = nothing
 
 """
     initecologicaldata()
@@ -12,10 +13,10 @@ const INDDATA = "individuals"
 Create output files for each data group collected by the nature model.
 """
 function initecologicaldata(model::AgentBasedModel)
-    newdataoutput!(model, POPTABLE, ["Date", "Species", "Abundance"],
-                   savepopulationdata, @param(nature.popoutfreq))
-    newdataoutput!(model, INDDATA, ["Date","ID","X","Y","Species","Sex","Age"],
-                   saveindividualdata, @param(nature.indoutfreq))
+    newdataoutput!(model, "populations", ["Date", "Species", "Abundance"],
+                   savepopulationdata, @param(nature.popoutfreq), visualisemap)
+    newdataoutput!(model, "individuals", ["Date","ID","X","Y","Species","Sex","Age"],
+                   saveindividualdata, @param(nature.indoutfreq), populationtrends)
 end
 
 """
-- 
GitLab