plot_sens_pliocene <- function(dataset, calib_data, calib_em = NULL, source,
var_future = "RCP85_2100", dobias = NA) {
#' Plot sensitivity of projections to Pliocene minimum value.
#'
#' For Extended Data Figure 1a,b (source = "Simulated") and
#' c (source = "Emulated"). In theory other RCPs can be plotted, but this is
#' untested.
#' @param dataset Dataset to use, whether simulated or emulated.
#' @param calib_data List of calibration data: c(mean, sd) for Pliocene, LIG
#' and present. List names are set in main(): "PLIO", "LIG" and "RCP45_pres".
#' @param calib_em Calibration index for emulated ensemble: do not use for
#' source = "Simulated".
#' @param source Data type: "Simulated" or "Emulated".
#' @param var_future Variable to plot vs Pliocene minimum (Deprecated: only
#' tested for RCP8.5 at 2100).
#' @param dobias Bias on or off (simulated only) or both (for emulated).
#' @examples
#' \dontrun{
#' # ED Figure 1a (simulated, bias off)
#' plot_sens_pliocene(dataset = sim_data, calib_data = calib_data,
#' source = "Simulated", dobias = FALSE)
#'
#' # ED Figure 1b (simulated, bias on)
#' plot_sens_pliocene(dataset = sim_data, calib_data = calib_data,
#' source = "Simulated", dobias = TRUE)
#'
#' # ED Figure 1c (emulated, bias all continuous values)
#' plot_sens_pliocene(dataset = sim_data, calib_data = calib_data,
#' alib_em = calib_em, source = "Emulated")
#' }
# ____________________________________________________________________________
# PLOT SENSITIVITY OF RESULTS TO PLIOCENE LOWER BOUND
# Extended Data Figure 1
# ____________________________________________________________________________
print(paste(
"PlotSensPliocene(): Plotting sensitivity of",
source, "data to Pliocene min"
))
# Pass args to relevant names
if (source == "Simulated") {
if (!is.null(calib_em)) {
warning("Do not provide calib_em for simulated dataset option")
}
sim_data <- dataset
}
if (source == "Emulated") {
if (!is.na(dobias)) {
warning("Cannot choose bias value for emulated ensemble:
must be missing or NA", immediate = TRUE)
return
}
if (is.null(calib_em)) {
warning("Must provide calibration index for emulated data",
immediate = TRUE
)
return
}
em_data <- dataset
}
# Convert to human readable names
if (is.na(dobias)) {
bias_name <- "both"
} else {
if (dobias == 0) bias_name <- "off"
if (dobias == 1) bias_name <- "on"
}
print(paste("Bias:", bias_name))
# RCP name for colours
myrcp <- strsplit(var_future, "_")[[1]][1]
# X values to plot; max poss for ensemble data is 11.5
pliocene_minima <- seq(0, 11.5, by = 0.1)
# Text size
size_axis_fig2 <- 0.6
size_lab_fig2 <- 0.6
# Plot mean and sd (simulated) or quantiles (emulated)
if (source == "Simulated") {
sim_plio_mean <- rep(NA, length(pliocene_minima))
sim_plio_sd <- rep(NA, length(pliocene_minima))
}
if (source == "Emulated") {
em_plio_mode <- rep(NA, length(pliocene_minima))
quant_list <- c(0.05, 0.25, 0.5, 0.75, 0.95)
em_plio_quantiles <- list()
for (quant in quant_list) {
em_plio_quantiles[[as.character(quant)]] <-
rep(NA, length(pliocene_minima))
}
}
# Bias on/off and LIG calibration for simulator ensemble (emulated is below)
if (source == "Simulated") {
if (is.na(dobias)) {
sim_lig_post <- sim_data[sim_data$LIG >
(calib_data[["LIG"]][1] - calib_data[["LIG"]][2]) &
sim_data$LIG <
(calib_data[["LIG"]][1] + calib_data[["LIG"]][2]), ]
} else {
sim_lig_post <- sim_data[sim_data$BIAS == dobias &
sim_data$LIG > (calib_data[["LIG"]][1] - calib_data[["LIG"]][2]) &
sim_data$LIG < (calib_data[["LIG"]][1] + calib_data[["LIG"]][2]), ]
}
}
# Loop through Pliocene minimum values
# Calculate all the mean/s.d. or quantile/mode values
for (pm in 1:length(pliocene_minima)) {
plio_min <- pliocene_minima[pm]
# Calibrate simulated with Pliocene (LIG was above)
# Max is written as central value plus width
if (source == "Simulated") {
sim_plio_post <-
sim_lig_post[
sim_lig_post$PLIO > plio_min &
sim_lig_post$PLIO <
(calib_data[["PLIO"]][1] + calib_data[["PLIO"]][2]),
var_future
]
}
# Calibrate emulated with Pliocene and LIG
if (source == "Emulated") {
# Bit convoluted: take mean of current min and fixed max
# 'Error' down from mean is difference between this and current min
plio_obs <- mean(c(
plio_min, calib_data[["PLIO"]][1] + calib_data[["PLIO"]][2]
))
plio_err <- plio_obs - plio_min
tot_err_down <- sqrt((plio_err**2 + e$discrep[["PLIO"]]**2 +
em_data[, "PLIO_sd"]**2))
# Error up i.e. for upper bound is usual mean + usual total error
tot_err_up <- sqrt((calib_data[["PLIO"]][2]**2 +
e$discrep[["PLIO"]]**2 +
em_data[, "PLIO_sd"]**2))
# Indices
calib_plio_down <- em_data[, "PLIO"] > plio_obs - tot_err_down
calib_plio_up <- em_data[, "PLIO"] < calib_data[["PLIO"]][1] + tot_err_up
# Calibration of emulated with present, LIG and current Pliocene range
em_plio_post <- em_data[calib_em[["present"]] & calib_em[["LIG"]] &
calib_plio_up & calib_plio_down, var_future]
}
# If found data OK then calculate mean + sd / quantiles + mode
if (source == "Simulated" && length(sim_plio_post) > 1) {
sim_plio_mean[pm] <- mean(sim_plio_post, na.rm = TRUE)
sim_plio_sd[pm] <- sd(sim_plio_post, na.rm = TRUE)
}
if (source == "Emulated" && length(em_plio_post) > 1) {
for (quant in quant_list) {
em_plio_quantiles[[as.character(quant)]][pm] <-
quantile(em_plio_post, quant, na.rm = TRUE)
}
# Mode
em_plio_mode[pm] <-
density(em_plio_post)$x[which.max(density(em_plio_post)$y)]
}
} # for each x-value
# ____________________________________________________________________________
# EXTENDED DATA FIGURE 1a, b
# RCP8.5 at 2100 mean and s.d. vs PLIO minimum
# ____________________________________________________________________________
if (source == "Simulated") {
plot(pliocene_minima[!is.na(sim_plio_mean)],
sim_plio_mean[!is.na(sim_plio_mean)],
type = "l", col = e$cols_rcp_dark[[myrcp]], lwd = 2,
axes = FALSE, frame.plot = TRUE, xlab = "", ylab = "",
ylim = range(e$var_breaks[[var_future]]), yaxs = "i",
xlim = range(pliocene_minima), xaxs = "i", main = ""
)
# Y axes
ticks_y <- seq(min(e$var_breaks[[var_future]]),
max(e$var_breaks[[var_future]]),
by = 50
)
minor_ticks_y <- seq(min(e$var_breaks[[var_future]]),
max(e$var_breaks[[var_future]]),
by = 10
)
axis(
side = 2, at = ticks_y, labels = ticks_y,
cex.axis = size_axis_fig2, cex.lab = size_lab_fig2
)
axis(side = 2, at = minor_ticks_y, labels = FALSE, tcl = 0.1)
axis(side = 4, at = ticks_y, labels = FALSE)
axis(side = 4, at = minor_ticks_y, labels = FALSE, tcl = 0.1)
if (bias_name == "off") {
mtext(paste(
"Mean and std dev SLE for",
e$var_labels[[var_future]]
),
side = 2, line = 1.2, cex = size_lab_fig2
)
}
# X axis
ticks_x <- seq(min(pliocene_minima), max(pliocene_minima))
minor_ticks_x <- seq(min(pliocene_minima), max(pliocene_minima), by = 0.2)
axis(
side = 1, at = ticks_x, labels = ticks_x,
cex.axis = size_axis_fig2, cex.lab = size_lab_fig2
)
axis(side = 1, at = minor_ticks_x, labels = FALSE, tcl = 0.1)
mtext("Lower bound Pliocene (m SLE)",
side = 1, line = 1.1,
cex = size_lab_fig2
)
polygon(c(
pliocene_minima[!is.na(sim_plio_mean)],
rev(pliocene_minima[!is.na(sim_plio_mean)])
),
c(
sim_plio_mean[!is.na(sim_plio_mean)] +
sim_plio_sd[!is.na(sim_plio_mean)],
rev(sim_plio_mean[!is.na(sim_plio_mean)] -
sim_plio_sd[!is.na(sim_plio_mean)])
),
col = e$cols_rcp_light[[myrcp]], border = NA
)
lines(pliocene_minima[!is.na(sim_plio_mean)],
sim_plio_mean[!is.na(sim_plio_mean)] + 2 *
sim_plio_sd[!is.na(sim_plio_mean)],
lty = 3, col = e$cols_rcp_dark[[myrcp]]
)
lines(pliocene_minima[!is.na(sim_plio_mean)],
sim_plio_mean[!is.na(sim_plio_mean)] - 2 *
sim_plio_sd[!is.na(sim_plio_mean)],
lty = 3, col = e$cols_rcp_dark[[myrcp]]
)
if (bias_name == "off") sublabel <- "a"
if (bias_name == "on") sublabel <- "b"
}
# ____________________________________________________________________________
# EXTENDED DATA FIGURE 1c
# RCP8.5 at 2100 quantiles and mode vs PLIO minimum
# ____________________________________________________________________________
if (source == "Emulated") {
plot(pliocene_minima, em_plio_quantiles[["0.5"]],
type = "l", col = e$cols_rcp_dark[[myrcp]], lwd = 2,
xlab = "", ylab = "", main = "", axes = FALSE, frame.plot = TRUE,
ylim = range(e$var_breaks[[var_future]]), yaxs = "i",
xlim = range(pliocene_minima), xaxs = "i"
)
# Y axes
ticks_y <- seq(min(e$var_breaks[[var_future]]),
max(e$var_breaks[[var_future]]),
by = 50
)
minor_ticks_y <- seq(min(e$var_breaks[[var_future]]),
max(e$var_breaks[[var_future]]),
by = 10
)
axis(
side = 2, at = ticks_y, labels = ticks_y,
cex.axis = size_axis_fig2, cex.lab = size_lab_fig2
)
axis(side = 2, at = minor_ticks_y, labels = FALSE, tcl = 0.1)
axis(side = 4, at = ticks_y, labels = FALSE)
axis(side = 4, at = minor_ticks_y, labels = FALSE, tcl = 0.1)
mtext(paste("Mode and quantiles SLE for", e$var_labels[[var_future]]),
side = 2, line = 1.2, cex = size_lab_fig2
)
# X axis
ticks_x <- seq(min(pliocene_minima), max(pliocene_minima))
minor_ticks_x <- seq(min(pliocene_minima), max(pliocene_minima), by = 0.2)
axis(
side = 1, at = ticks_x, labels = ticks_x,
cex.axis = size_axis_fig2, cex.lab = size_lab_fig2
)
axis(side = 1, at = minor_ticks_x, labels = FALSE, tcl = 0.1)
mtext("Lower bound Pliocene (m SLE)",
side = 1, line = 1.1, cex = size_lab_fig2
)
polygon(c(pliocene_minima, rev(pliocene_minima)),
c(em_plio_quantiles[["0.95"]], rev(em_plio_quantiles[["0.05"]])),
col = e$cols_rcp_light[[myrcp]], border = e$cols_rcp_dark[[myrcp]]
)
polygon(c(pliocene_minima, rev(pliocene_minima)),
c(em_plio_quantiles[["0.25"]], rev(em_plio_quantiles[["0.75"]])),
col = e$cols_rcp_light[[myrcp]], border = e$cols_rcp_dark[[myrcp]]
)
points(pliocene_minima, em_plio_mode, pch = "*", cex = 0.8)
sublabel <- "c"
}
# Additions to either kind of plot
abline(v = 5.0, lwd = 0.5, col = "darkgrey")
abline(v = 10.0, lwd = 0.5, col = "darkgrey")
text(0, 0.95 * max(e$var_breaks[[var_future]]), sublabel,
font = 2, cex = 0.7, pos = 4
)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.