Skip to contents

Creates a solar diagram comparing quantitative prediction models with an observation vector. The horizontal coordinate is normalized mean error (ME*) and the vertical coordinate is standardized unbiased root mean square difference (SDE*).

Usage

gg_solar(
  mods,
  obs,
  colorval = NULL,
  colorval.name = NULL,
  colour_by = c("efficiency", "model", "correlation", "r2"),
  x.axis_begin = -1,
  x.axis_end = 1,
  y.axis_end = 1.1,
  by = 0.1,
  label = FALSE,
  point_size = 7,
  label_size = 4,
  na.rm = TRUE,
  legend = TRUE,
  reference = TRUE
)

Arguments

mods

Numeric vector, list of numeric vectors, or numeric matrix/data frame with one model per column. Rows match obs in order. Supplied model names must be unique; missing names are generated.

obs

A numeric observation vector.

colorval

Optional finite numeric vector with one value per model, in model order (names do not reorder values). When supplied, it overrides the continuous metric selected by colour_by.

colorval.name

Optional point-colour legend title. The title can also be replaced afterwards with labs(colour = ...).

colour_by

Character string defining point colouring. "efficiency" uses R-squared / NSE / MEC and is the default; "model" gives every model a categorical colour and model-name legend; "correlation" uses Pearson correlation; and "r2" uses squared Pearson correlation.

x.axis_begin

Lower endpoint of the manually drawn horizontal reference axis.

x.axis_end

Upper endpoint of the manually drawn horizontal reference axis.

y.axis_end

Upper endpoint of the manually drawn vertical reference axis. Defaults to 1.1 so that the outer correlation circle at 1 and points lying on it remain clearly visible.

by

Spacing between manually drawn reference-axis ticks.

label

Logical; draw model names beside points using ggrepel?

point_size

Numeric point size.

label_size

Numeric size of model labels.

na.rm

Logical; remove incomplete observation-prediction pairs separately for each model? If FALSE, missing pairs cause an error because diagram coordinates cannot be calculated. The default is TRUE.

legend

Logical; show the point-colour and correlation-region legends?

reference

Logical; draw the original correlation regions and outer reference circle?

Value

A ggplot2 plot object that can be extended with ordinary ggplot2 layers, scales, labels, themes, and coordinates.

Details

The default pale-yellow correlation regions follow Wadoux, Walvoort, and Brus (2022). Points are coloured by the model-efficiency coefficient R-squared / NSE / MEC by default.

Missing pairs are removed separately per model when na.rm = TRUE. Two complete pairs with non-zero observation SD are required.

By default, point colour represents the model-efficiency coefficient (uppercase R-squared), equivalent to NSE and MEC in modelskill. This must not be confused with squared Pearson correlation, available with colour_by = "r2". The default legend title for the efficiency colour scale is simply .

The function returns an ordinary ggplot2 object. Styling that belongs to the ggplot2 ecosystem can therefore be applied after the function call. Use labs() for titles, theme() for typography and legend placement, scale_colour_*() to replace the point-colour scale, and scale_fill_*() to replace the correlation-region palette.

Reference-axis arguments control the manually drawn solar axes rather than clipping limits. Observations outside those reference axes remain visible. To zoom while retaining equal x and y scaling, add a new coord_fixed() layer with the desired limits.

Coordinates and labels

The horizontal coordinate is normalized mean error (nME; ME*) and the vertical coordinate is standardized unbiased root mean square difference (sde; SDE*). Correlation-region radii are calculated exactly from their correlation thresholds as sqrt(1 - r^2); their interpretation requires the normalization assumptions documented in diagram_stats().

Interpretation

The solar diagram uses the error decomposition $$\mathrm{RMSE}^{*2} = \mathrm{ME}^{*2} + \mathrm{SDE}^{*2},$$ where ME*, SDE*, and RMSE* are respectively mean error, centred root mean square difference, and RMSE divided by the population-moment observation standard deviation. The distance from the origin is RMSE*. The origin is perfect prediction; points on the vertical axis have no mean error; negative ME* indicates overprediction under the package convention obs - pred; and positive ME* indicates underprediction.

Points inside the outer RMSE* = 1 circle improve on predicting the observed mean (equivalently, MEC/NSE/R2 is positive). The pale-yellow regions give lower bounds on correlation, rather than exact correlation values. For example, a point near the origin and inside the correlation-greater-than-0.9 region has low total error and strong pattern agreement; a point far left or right is systematically biased; and a point high on the vertical axis is unbiased but has substantial pattern or spread disagreement.

ggplot2 customization

Arguments that change the statistical content or core diagram construction are exposed directly by gg_solar(). Ordinary appearance is intentionally left to ggplot2. For example, users can add labs(), theme(), a replacement scale_colour_*() or scale_fill_*(), or a replacement coord_fixed().

References

Wadoux, A. M. J.-C., Walvoort, D. J. J., and Brus, D. J. (2022). An integrated approach for the evaluation of quantitative soil maps through Taylor and solar diagrams. Geoderma, 405, 115332. doi:10.1016/j.geoderma.2021.115332

Jolliff, J. K., Kindle, J. C., Shulman, I., Penta, B., Friedrichs, M. A. M., Helber, R., and Arnone, R. A. (2009). Summary diagrams for coupled hydrodynamic-ecosystem model skill assessment. Journal of Marine Systems, 76, 64-82. doi:10.1016/j.jmarsys.2008.05.014

Examples

obs <- c(1, 2, 3, 4, 5)
mods <- list(perfect = obs, biased = obs + 1)

# Default: point colour represents R-squared / NSE / MEC.
gg_solar(mods, obs)


# Give every model a categorical colour and a model-name legend.
p_models <- gg_solar(mods, obs, colour_by = "model")

# Write model names directly beside points.
p_labels <- gg_solar(mods, obs, label = TRUE)

# Standard ggplot2 customization.
p_custom <- gg_solar(mods, obs) +
  ggplot2::labs(title = "Model performance") +
  ggplot2::theme(legend.position = "bottom")
# Print p_models, p_labels or p_custom to display a variant.