Visualizing outputs and data

Output structure

PlantSimEngine's run! functions return for each timestep the state of the variables that were requested using the tracked_outputs kwarg (or the state of every variable if this kwarg was left unspecified). Multi-scale simulations also indicate which organ and MTG node these state variables are related to.

Here's an example indicating how to plot output data using CairoMakie, a package used for plotting.

# ] add PlantSimEngine, PlantMeteo
using PlantSimEngine, PlantMeteo, Dates

# Include the model definition from the examples folder:
using PlantSimEngine.Examples

# Import the example meteorological data:
meteo_day = read_weather(joinpath(pkgdir(PlantSimEngine), "examples/meteo_day.csv"), duration=Dates.Day)

# Define the list of models for coupling:
models = ModelMapping(
    ToyLAIModel(),
    Beer(0.6),
    status=(TT_cu=cumsum(meteo_day[:, :TT]),),  # Pass the cumulated degree-days as input to `ToyLAIModel`, this could also be done using another model
)

# Run the simulation:
sim_outputs = run!(models, meteo_day)
sim_outputs[1:3,:] # show the first 3 rows of the output
TimeStepTable{Status{(:TT_cu, :LAI, :aPPFD)...}(3 x 3):
TT_cu LAI aPPFD
Float64 Float64 Float64
1 0.0 0.00554988 0.0476221
2 0.0 0.00554988 0.0260688
3 0.0 0.00554988 0.0377774

The output data is displayed as a by default as a TimeStepTable. It is also possible to filter which variables are kept via the optional tracked_outputs keyword argument.

Plotting outputs

Using CairoMakie, one can plot out selected variables :

Note

You will need to add CairoMakie to your environment through Pkg mode first.

# Plot the results:
using CairoMakie

fig = Figure(resolution=(800, 600))
ax = Axis(fig[1, 1], ylabel="LAI (m² m⁻²)")
lines!(ax, sim_outputs[:TT_cu], sim_outputs[:LAI], color=:mediumseagreen)

ax2 = Axis(fig[2, 1], xlabel="Cumulated growing degree days since sowing (°C)", ylabel="aPPFD (mol m⁻² d⁻¹)")
lines!(ax2, sim_outputs[:TT_cu], sim_outputs[:aPPFD], color=:firebrick1)

fig
Example block output

TimeStepTables and DataFrames

The output data is usually stored in a TimeStepTable structure defined in PlantMeteo.jl, which is a fast DataFrame-like structure with each time step being a Status. It can be also be any Tables.jl structure, such as a regular DataFrame. Weather data is also usually stored in a TimeStepTable but with each time step being an Atmosphere.

Another simple way to get the results is to transform the outputs into a DataFrame. Which is very easy because the TimeStepTable implements the Tables.jl interface:

using DataFrames
sim_outputs_df = PlantSimEngine.convert_outputs(sim_outputs, DataFrame)
sim_outputs_df[[1, 2, 3, 363, 364, 365], :]
6×3 DataFrame
RowTT_cuLAIaPPFD
Float64Float64Float64
10.00.005549880.0476221
20.00.005549880.0260688
30.00.005549880.0377774
42189.270.00.0
52192.90.00.0
62193.820.00.0

It is also possible to create DataFrames from specific variables:

df = DataFrame(aPPFD=sim_outputs[:aPPFD][1], LAI=sim_outputs.LAI[1], Ri_PAR_f=meteo.Ri_PAR_f[1])

Which can also be useful for Parameter fitting .