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
obsin 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 isTRUE.- 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 R².
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.
