Skip to contents

The calibration of the SWAT+ model is a complex process that involves many steps. One of the most important steps is the visual inspection of the model results. This document provides an overview of the functions available in the SWATtunR package for plotting SWAT+ model calibration and validation results. Functions intended to be used for plotting at different stages of the SWAT+ model calibration and validation process and not in sequential order. To run these function step 6 or/and step 6a should be completed successfully. Same packages should be loaded as in the step 1.

1. Dotty plots

For comparison, you can use the function plot_dotty. It allows examining model performance results versus parameter values.

The function has the following arguments:

  • par: a data frame of model parameter values for each simulation.
  • var: model performance result vector or list of vectors to be plotted against parameter values.
  • y_label: the label or vector of labels for the y-axis. Default is 'y'.
  • n_col: number of columns in the facet grid. Default is 3.
  • y_lim: defines limits for the y-axis. Default is NULL.
  • y_inter: Y-axis intercept value. Default is NULL.
  • trend: logical, indicating whether to add a trend line. Default is FALSE.
  • run_ids: a numeric vector of run IDs to be highlighted in the plot.
  • low_up: logical, TRUE if the whole possible parameter range should be used for the x-axis. Default is FALSE.
# Example of usage:
plot_dotty(sim_flow$parameter$values, obj_tbl$nse)
plot_dotty(sim_flow$parameter$values, obj_tbl$kge, n_col = 5, y_lim = c(0.5, 0.9))
plot_dotty(sim_flow$parameter$values, obj_tbl$pbias, n_col = 5)
plot_dotty(sim_flow$parameter$values, obj_tbl$nse, run_ids = c(1, 2, 5), low_up = TRUE)
plot_dotty(sim_flow$parameter$values, obj_tbl$kge, trend = TRUE)

Dotty plots can also be created for multiple variables in the simulation list. In this case, the dotty plot will be displayed on the same plot with different colors for each variable. Trends can also be added to the plot. Water flow and water quality variables can be plotted together on the same plot.

# Example of usage:
plot_dotty(par = sim_flow$parameter$values, 
           var = list(obj_tbl_m$obj_tbl_list$flo_day_52$nse, 
                      obj_tbl_m$obj_tbl_list$no3_day_52_conc$nse,
                      obj_tbl_m$obj_tbl_list$gwd$nse), 
           y_label =  c('Flow at 52r (m3/s)', 
                        "Nitrate at 52r (mgN/l)", 
                        "Groundwater depth (m)"),
           trend = TRUE)

2. Simulation vs observed values time series

To plot the results of selected variable sets simulation results versus observed, you can use the plot_selected_sim. This function allows you to compare the selected simulated data with the observation data. The function has several arguments:

  • sim: object from SWATrunR.
  • obs: dataframe for the observed data with two columns: ‘date’ and ‘value’.
  • par_name: name of the parameter set to be used (default is NULL, which selects the first record). If you have multiple parameter sets, you can use this argument to select the one you want to use. For example, par_name = "flo_day" or par_name = "no3_day_conc".
  • run_ids: character vector with the IDs of the runs to be used in the plot.
  • run_sel: character vector with the ID or IDs of the runs to be emphasized in the plot.
  • plot_bands: logical. If TRUE, the plot will include lower and upper bands of results.
  • period: character. If NULL, the plot will be based on the original time step of the simulation. Other examples are “day”, “week”, “month”, “year”, etc. If “average monthly”, the plot will be based on the multi-annual monthly values.
  • fn_summarize: function to recalculate the time interval (default is “mean”), other options include “mean”, “median”, “sum”, “min”, “max”, etc.
  • x_label: character. Label for the x-axis. Default is “Date”.
  • y_label: character. Label for the y-axis. Default is “Discharge (m³/s)”.
##Simple example
plot_selected_sim(sim_flow, obs, par_name = "flo_day_52", run_ids = run_sel_ids)

This function can also be used to plot the average monthly values of the selected variable set. In this case, the period argument should be set to “average monthly”.

# Another example how all function arguments are used
plot_selected_sim(sim = sim_flow,
                  obs = obs,
                  par_name = "flo_day_52",
                  run_ids = run_sel_ids,
                  run_sel = run_sel_ids[1],
                  plot_bands = TRUE,
                  period = "average monthly",
                  fn_summarize = "mean",
                  x_label = "Month",
                  y_label = "Monthly flow average (m<sup>3</sup> s<sup>-1</sup>)")

3. Plotting parameter identifiability

The parameter identifiability plot is prepared based on the methodology provided the article of Guse et al. (2020). The plot below shows the ranges of parameter,s which perform better for a certain performance metric. The run_fraction defines the fraction of simulations which should be considered in the analysis (with 1000 runs this value should maybe not be lower than 0.2, too large values also do not make much sense). For 5000 runs 0.1 would be a good value.

In case you used multiple variables in performance calculation, you can use obj_tbl_list$var_name to select the variable for which you want to plot parameter identifiability. Similar adjustment could be done for dotty plots.

# Usage example
plot_parameter_identifiability(parameters = sim_flow$parameter$values,
                               objectives = 
                                 select(obj_tbl, -starts_with(c('rank', 'run', 'rsr'))) 
                               ## This starts_with vector could be amended with
                               ## other columns which should not be considered"
                               )

4. Plotting parameter sensitivity

To perform an OAT (One-At-A-Time) analysis could be used to visualize the sensitivity of the model to the parameters. The function plot_oat allows you to plot the results of the OAT analysis.

# Example of usage:
# If you want to perform an OAT analysis
# Select the parameter combination around which you want to do the OAT analysis
par_center_id <- 2

# Extract the center parameter set and assign again the "full" names to be used
# with SWATrunR
par_center <- sim_flow$parameter$values[par_center_id, ] %>% 
  set_names(sim_flow$parameter$definition$full_name)

# You can define your own parameter boundaries for the selected parameters
# Here a way how you can quickly extract the boundaries from the last simulation
par_bnd <- sim_flow$parameter$values %>% 
  map(., ~ c(min(.x), max(.x))) %>% 
  map(., ~ round(.x, 3)) %>% 
  bind_cols(.) %>% 
  set_names(sim_flow$parameter$definition$full_name)

# Sample the OAT parameter set and run the simulations
par_oat <- sample_oat(par = par_bnd, par_center = par_center)

par_oat <- filter(par_oat, parameter %in% c('center', 'bf_max.aqu | change = absval'))

sim_oat <- run_swatplus(project_path = model_path,
                        output = list(
                          flo_day = define_output(file = 'channel_sd_day',
                                                  variable = 'flo_out',
                                                  unit = cha_ids)),
                        parameter = par_oat[,3:ncol(par_oat)],
                        n_thread = n_cores)
# save_file = 'sim_oat')

# To visualize the OAT runs e.g. for the parameter surlag:
plot_oat(sim = sim_oat, obs = obs, variable = 'flo_day_52')

5. Plotting the calibration vs validation

To compare the calibration and validation results, you can use the plot_calval_comparison function. This function allows you to compare the calibration and validation results for the selected variable set. It could also be used to compare the results of different calibration runs.

# Example of usage:
# Plot results on the time series figure for validation period
plot_calval_comparison(obj_tbl_cal, obj_tbl_val, 
                       indexes = c("nse", "kge", "pbias", "r2", "mae" ))

References

Guse, Björn, Jens Kiesel, Matthias Pfannerstill, and Nicola Fohrer. 2020. Assessing parameter identifiability for multiple performance criteria to constrain model parameters.” Hydrological Sciences Journal 65 (7): 1158–72. https://doi.org/10.1080/02626667.2020.1734204.