This analysis evaluates the performance of various precipitation and
climate models (CHIRPS, PERSIANN, TAMSATV3, ARCV2, ERA5) against
ground-based observations using Taylor diagrams in R. Taylor diagrams
provide a concise visualization of model performance by comparing
correlation, standard deviation, and centered root-mean-square error
(RMSE). The analysis uses synthetic data representing annual and
seasonal (JF, MAM, JJAS, OND) precipitation measurements. By leveraging
the plotrix and openair packages, we assess
the models’ ability to replicate observed precipitation patterns,
offering insights into their accuracy and reliability for climate
studies.
The following packages are required for the analysis. Install them
using: install.packages('package_name').
library(plotrix)
library(openair)
library(tidyr)
library(dplyr)
Synthetic data is generated to represent observed precipitation (AIRPORT) and model outputs (CHIRPS, PERSIANN, TAMSATV3, ARCV2, ERA5) for annual and seasonal periods (JF, MAM, JJAS, OND). The data simulates realistic variations with different means and standard deviations.
set.seed(123)
n <- 50
# Annual data
OB <- rnorm(n, mean=15, sd=3) # AIRPORT
CH <- OB * 0.9 + rnorm(n, sd=2) # CHIRPS
PE <- OB * 0.8 + rnorm(n, sd=2.5) # PERSIANN
TA <- OB * 0.7 + rnorm(n, sd=3) # TAMSATV3
AR <- OB * 0.85 + rnorm(n, sd=2.2) # ARCV2
ER <- OB * 0.95 + rnorm(n, sd=1.8) # ERA5
# Seasonal data
JF.OB <- rnorm(n, mean=12, sd=2.5)
JF.CH <- JF.OB * 0.88 + rnorm(n, sd=2.1)
JF.PE <- JF.OB * 0.78 + rnorm(n, sd=2.6)
JF.TA <- JF.OB * 0.68 + rnorm(n, sd=3.1)
JF.AR <- JF.OB * 0.83 + rnorm(n, sd=2.3)
JF.ER <- JF.OB * 0.93 + rnorm(n, sd=1.9)
MAM.OB <- rnorm(n, mean=18, sd=3.2)
MAM.CH <- MAM.OB * 0.91 + rnorm(n, sd=2.2)
MAM.PE <- MAM.OB * 0.81 + rnorm(n, sd=2.7)
MAM.TA <- MAM.OB * 0.71 + rnorm(n, sd=3.2)
MAM.AR <- MAM.OB * 0.86 + rnorm(n, sd=2.4)
MAM.ER <- MAM.OB * 0.94 + rnorm(n, sd=2.0)
JJAS.OB <- rnorm(n, mean=22, sd=3.8)
JJAS.CH <- JJAS.OB * 0.92 + rnorm(n, sd=2.4)
JJAS.PE <- JJAS.OB * 0.82 + rnorm(n, sd=2.9)
JJAS.TA <- JJAS.OB * 0.72 + rnorm(n, sd=3.4)
JJAS.AR <- JJAS.OB * 0.87 + rnorm(n, sd=2.6)
JJAS.ER <- JJAS.OB * 0.96 + rnorm(n, sd=2.1)
OND.OB <- rnorm(n, mean=14, sd=2.8)
OND.CH <- OND.OB * 0.89 + rnorm(n, sd=2.0)
OND.PE <- OND.OB * 0.79 + rnorm(n, sd=2.5)
OND.TA <- OND.OB * 0.69 + rnorm(n, sd=3.0)
OND.AR <- OND.OB * 0.84 + rnorm(n, sd=2.2)
OND.ER <- OND.OB * 0.92 + rnorm(n, sd=1.7)
A Taylor diagram is created to compare the annual performance of the
models against observations using the plotrix package. Each
model is represented with a distinct color.
oldpar <- taylor.diagram(OB, CH, add=FALSE, pch=19, pos.cor=TRUE,
xlab="Standard deviation", ylab="Standard Deviation",
main="Annual Precipitation Model Comparison",
show.gamma=TRUE, ngamma=10, gamma.col="green",
sd.arcs=1, ref.sd=TRUE, sd.method="sample",
grad.corr.lines=c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99),
col="blue", pcex=1.5, cex.axis=1.1, normalize=TRUE)
taylor.diagram(OB, PE, add=TRUE, col="black", pcex=1.5, cex.axis=1.1, normalize=TRUE)
taylor.diagram(OB, TA, add=TRUE, col="pink", pcex=1.5, cex.axis=1.1, normalize=TRUE)
taylor.diagram(OB, AR, add=TRUE, col="brown", pcex=1.5, cex.axis=1.1, normalize=TRUE)
taylor.diagram(OB, ER, add=TRUE, col="green", pcex=1.5, cex.axis=1.1, normalize=TRUE)
legend("left", legend=c("AIRPORT", "CHIRPS", "PERSIANN", "TAMSATV3", "ARCV2", "ERA5"),
pch=c(15, 19, 19, 19, 19, 19), col=c("darkgreen", "blue", "black", "pink", "brown", "green"), cex=0.7)
Separate Taylor diagrams are generated for each season (JF, MAM, JJAS, OND) to evaluate model performance across different climatic periods.
require(plotrix)
taylor.diagram(JF.OB, JF.CH, col="blue", pos.cor=F,pcex=1.5,normalize=F)
taylor.diagram(JF.OB, JF.PE,add=TRUE, col="black", pcex=1.5,normalize=F)
taylor.diagram(JF.OB, JF.TA,add=TRUE, col="pink", pcex=1.5,normalize=F)
taylor.diagram(JF.OB, JF.AR,add=TRUE, col="brown", pcex=1.5,normalize=F)
taylor.diagram(JF.OB, JF.ER,add=TRUE, col="green", pcex=1.5,normalize=F)
require(plotrix)
taylor.diagram(MAM.OB, MAM.CH, col="blue", pos.cor=F,pcex=1.5,normalize=F)
taylor.diagram(MAM.OB, MAM.PE,add=TRUE, col="black", pcex=1.5,normalize=F)
taylor.diagram(MAM.OB, MAM.TA,add=TRUE, col="pink", pcex=1.5,normalize=F)
taylor.diagram(MAM.OB, MAM.AR,add=TRUE, col="brown", pcex=1.5,normalize=F)
taylor.diagram(MAM.OB, MAM.ER,add=TRUE, col="green", pcex=1.5,normalize=F)
require(plotrix)
taylor.diagram(JJAS.OB, JJAS.CH, col="blue", pos.cor=F,pcex=1.5,normalize=F)
taylor.diagram(JJAS.OB, JJAS.PE,add=TRUE, col="black", pcex=1.5,normalize=F)
taylor.diagram(JJAS.OB, JJAS.TA,add=TRUE, col="pink", pcex=1.5,normalize=F)
taylor.diagram(JJAS.OB, JJAS.AR,add=TRUE, col="brown", pcex=1.5,normalize=F)
taylor.diagram(JJAS.OB, JJAS.ER,add=TRUE, col="green", pcex=1.5,normalize=F)
require(plotrix)
taylor.diagram(OND.OB, OND.CH, col="blue", pos.cor=F,pcex=1.5,normalize=F)
taylor.diagram(OND.OB, OND.PE,add=TRUE, col="black", pcex=1.5,normalize=F)
taylor.diagram(OND.OB, OND.TA,add=TRUE, col="pink", pcex=1.5,normalize=F)
taylor.diagram(OND.OB, OND.AR,add=TRUE, col="brown", pcex=1.5,normalize=F)
taylor.diagram(OND.OB, OND.ER,add=TRUE, col="green", pcex=1.5,normalize=F)
legend(30,53
,legend=c("OND.OBSERVATON","OND.CHIRPS","OND.PESERIANNCDR","OND.TAMSAT","OND.ARC","OND.ERA"),horiz=FALSE,
pch=c(15,19,19,19,19,19),col=c("darkgreen","red","blue","brown","orange","darkgreen"), cex=0.7)
par(mfrow=c(2,2))
colors <- c("blue", "black", "pink", "brown", "green")
plot_taylor_diagram <- function(season, main_title) {
obs <- get(paste0(season, ".OB"))
taylor.diagram(obs, get(paste0(season, ".CH")), col=colors[1], pch=19,
main=main_title, normalize=FALSE, pos.cor=TRUE)
for(i in 2:5) {
model <- c("PE", "TA", "AR", "ER")[i-1]
taylor.diagram(obs, get(paste0(season, ".", model)),
add=TRUE, col=colors[i], pch=19)
}
legend("topright", legend=c("CHIRPS", "PERSIANN", "TAMSATV3", "ARCV2", "ERA5"),
col=colors, pch=19, cex=0.8)
}
plot_taylor_diagram("JF", "Janvier-Février (JF)")
plot_taylor_diagram("MAM", "Mars-Mai (MAM)")
plot_taylor_diagram("JJAS", "Juin-Septembre (JJAS)")
plot_taylor_diagram("OND", "Octobre-Décembre (OND)")
par(mfrow=c(1,1))
Using the openair package, a Taylor diagram is created
to compare all models in a single plot, with data reformatted into a
long format for compatibility.
mod.dat <- data.frame(
date = seq.Date(from = as.Date("2000-01-01"), by = "day", length.out = n),
obs = OB, mod.CH = CH, mod.PE = PE, mod.TA = TA, mod.AR = AR, mod.ER = ER
)
mod.dat.long <- mod.dat %>%
pivot_longer(cols = starts_with("mod."),
names_to = "model",
values_to = "mod") %>%
mutate(model = gsub("mod.", "", model))
TaylorDiagram(mod.dat.long, obs = "obs", mod = "mod", group = "model",
main="Model Comparison (Openair)")
For further inquiries, please contact: