plot_age_length <- function(RBdata, RBfit = NULL, stan_obj = NULL, bubble = 7, sdlen = 0.95) {
if(all(is.na(RBdata@Age_length))) {
plot(NULL, NULL, typ = "n", xlab = "Age (accumulated degree years)", ylab = "Length", xlim = c(0, 1), ylim = c(0, 1))
text(x = 0.5, y = 0.5, labels = "No age-length data.")
return(invisible())
}
range_obs <- pretty(RBdata@Age_length)
n1 <- range_obs[2]
n2 <- pretty(quantile(RBdata@Age_length, na.rm = TRUE, probs = 0.9))[2]
if(n2 < n1) n1 <- 0.5 * n2
diameter_max <- bubble/n2
plot(NULL, NULL, typ = "n", xlab = "Age (accumulated degree years)", ylab = "Length",
xlim = range(RBdata@Age_adjust), ylim = range(RBdata@Length_bin))
for(i in 1:length(RBdata@Age)) {
for(j in 1:length(RBdata@Length_bin)) {
if(!is.na(RBdata@Age_length[i, j]) && RBdata@Age_length[i, j] > 0) {
points(RBdata@Age_adjust[i], RBdata@Length_bin[j], cex = 0.5 * diameter_max * pmin(RBdata@Age_length[i, j], n2), pch = 21,
bg = "grey80")
}
}
}
if(!is.null(RBfit)) {
order_vec <- order(RBdata@Age_adjust)
lines(RBdata@Age_adjust[order_vec], RBfit@report$Len_age[order_vec], col = "red", lwd = 3)
len_lims <- c(0.5 * (1 - sdlen), 1 - 0.5 * (1 - sdlen))
lines(RBdata@Age_adjust[order_vec], qnorm(len_lims[1], RBfit@report$Len_age, RBfit@report$sd)[order_vec], col = "red", lty = 2)
lines(RBdata@Age_adjust[order_vec], qnorm(len_lims[2], RBfit@report$Len_age, RBfit@report$sd)[order_vec], col = "red", lty = 2)
}
if(!is.null(stan_obj)) {
order_vec <- order(RBdata@Age_adjust)
sim <- stan_obj@sim
ind <- 1:(sim$warmup %/% sim$thin)
mcmc_samps <- lapply(sim$samples, function(x) lapply(x, `[`, -ind))
get_length_at_age <- function(Linf, K, RBdata) {
RBdata@L_stock * exp(-K * RBdata@Age_adjust) + Linf * (1 - exp(-K * RBdata@Age_adjust))
}
map_fn <- function(y, RBdata) {
res <- Map(get_length_at_age, Linf = y$Linf, K = y$K, MoreArgs = list(RBdata = RBdata))
do.call(rbind, res)
}
get_matrix <- function(x, RBdata) {
res <- lapply(x, map_fn, RBdata = RBdata)
do.call(rbind, res)
}
res <- get_matrix(mcmc_samps, RBdata)
lines(RBdata@Age_adjust[order_vec], colMeans(res)[order_vec], col = "red", lwd = 3)
}
legend("topright", legend = paste("N =", sum(RBdata@Age_length, na.rm = TRUE)), bty = "n", text.font = 2)
legend("bottomright", legend = c(n1, paste0(">", n2)), pt.cex = 0.5 * diameter_max * c(n1, n2), pt.bg = "grey80", pch = 21, horiz = TRUE)
return(invisible())
}
plot_length <- function(RBdata, RBfit = NULL) {
Length_bin <- RBdata@Length_bin
Length <- RBdata@Length
Length[is.na(Length) | Length <= 0] <- NA
if(!is.null(RBfit)) {
pred_N <- RBfit@report$survey_NL/sum(RBfit@report$survey_NL)
if(!all(is.na(Length))) pred_N <- sum(Length, na.rm = TRUE) * pred_N
ymax <- 1.1 * max(c(Length, pred_N), na.rm = TRUE)
barplot(Length, names.arg = Length_bin, space = 0, xlab = "Length", ylab = "Numbers-at-length", ylim = c(0, ymax))
lines(c(1:length(Length_bin)) - 0.5, pred_N, col = "red", lwd = 2, typ = "o", pch = 16)
if(sum(Length, na.rm = TRUE) > 0) legend("topright", legend = paste("N =", sum(Length, na.rm = TRUE)), bty = "n", text.font = 2)
#legend("topleft", legend = c("Observed", "Predicted"), col = c("black", "red"), pt.bg = c("grey80", "red"), pch = c(22, 16))
} else {
if(all(is.na(Length))) ymax <- 1 else ymax <- 1.1 * max(Length, na.rm = TRUE)
barplot(Length, names.arg = Length_bin, space = 0, xlab = "Length", ylab = "Numbers-at-length", ylim = c(0, ymax))
if(all(is.na(Length))) {
text(x = 0.5 * length(Length), y = 0.5, labels = "No length data.")
} else legend("topright", legend = paste("N =", sum(Length, na.rm = TRUE)), bty = "n", text.font = 2)
}
box()
return(invisible())
}
plot_stocking_density <- function(RBdata) {
plot(RBdata@Age, RBdata@stock_density, xlab = "Age", ylab = "Stocking density", typ = "o", pch = 16)
}
plot_Lstart <- function(RBdata) {
plot(RBdata@Age, RBdata@L_stock, xlab = "Age", ylab = "Length at stocking", typ = "o", pch = 16)
}
plot_age_length_residual <- function(RBfit, bubble = 7, add_title = TRUE) {
if(all(is.na(RBfit@RBdata@Age_length))) {
plot(NULL, NULL, typ = "n", xlab = "Age (accumulated degree years)", ylab = "Length", xlim = c(0, 1), ylim = c(0, 1))
text(x = 0.5, y = 0.5, labels = "No age-length data.")
return(invisible())
}
obs <- RBfit@RBdata@Age_length
obs[obs <= 0] <- NA
pred_N <- sum(RBfit@RBdata@Age_length, na.rm = TRUE) * RBfit@report$survey_N/sum(RBfit@report$survey_N)
resids <- (obs - pred_N)/sqrt(pred_N)
range_resids <- quantile(pretty(resids))[c(2, 4)]
diameter_max <- bubble/max(abs(range_resids))
plot(NULL, NULL, typ = "n", xlab = "Age (accumulated degree years)", ylab = "Length",
xlim = range(RBfit@RBdata@Age_adjust), ylim = range(RBfit@RBdata@Length_bin))
for(i in 1:length(RBfit@RBdata@Age)) {
for(j in 1:length(RBfit@RBdata@Length_bin)) {
if(!is.na(obs[i, j])) {
points(RBfit@RBdata@Age_adjust[i], RBfit@RBdata@Length_bin[j],
cex = 0.5 * diameter_max * pmin(abs(resids[i, j]), max(abs(range_resids))), pch = 21,
bg = ifelse(resids[i, j] > 0, "grey80", "white"))
}
}
}
if(add_title) title("Age-length residual")
legend("bottomright", legend = paste(c("<", ">"), range_resids), pt.cex = 0.5 * diameter_max * abs(range_resids),
pt.bg = ifelse(range_resids > 0, "grey80", "white"), pch = 21, horiz = TRUE)
return(invisible())
}
plot_length_residual <- function(RBfit, ylab = "Standardized\nPearson Residual") {
obs <- RBfit@RBdata@Length
obs[obs <= 0] <- NA
pred_N <- sum(obs, na.rm = TRUE) * RBfit@report$survey_NL/sum(RBfit@report$survey_NL)
resids <- (obs - pred_N)/sqrt(pred_N)
if(all(is.na(resids))) ylim <- c(0, 1) else {
if(all(resids < 0 | is.na(resids))) {
ylim <- c(1.1 * min(resids, na.rm = TRUE), 0.1)
} else if(all(resids > 0 | is.na(resids))) {
ylim <- c(-0.1, 1.1 * max(resids, na.rm = TRUE))
} else ylim <- 1.1 * range(resids, na.rm = TRUE)
}
barplot(rep(0, length(obs)), names.arg = RBfit@RBdata@Length_bin, space = 0, border = NA,
xlab = "Length", ylim = ylim)
if(all(is.na(obs))) {
text(x = 0.5 * length(obs), y = 0.5, labels = "No length data.")
} else {
lines(c(1:length(obs)) - 0.5, resids, lwd = 2, typ = "o", pch = 16)
abline(h = 0, lty = 3)
}
box()
return(invisible())
}
plot_selectivity <- function(RBfit, stan_obj = NULL) {
Length_bin <- RBfit@RBdata@Length_bin
barplot(rep(0, length(Length_bin)), names.arg = Length_bin, space = 0, border = NA,
xlab = "Length", ylab = "Selectivity", ylim = c(-0.1, 1.1), yaxp = c(0, 1, 2))
abline(h = 0, col = "grey")
if(is.null(stan_obj)) {
GN <- RBfit@report$sel_GN
ang <- RBfit@report$sel_angler
} else {
sim <- stan_obj@sim
ind <- 1:(sim$warmup %/% sim$thin)
mcmc_samps <- lapply(sim$samples, function(x) lapply(x, `[`, -ind))
get_sel <- function(L50, gamma, Len_bin) {
sel <- 1/(1 + exp(-gamma * (Len_bin - L50))); return(sel/max(sel))
}
map_fn <- function(y, Len, L50c, gammac) {
res <- Map(get_sel, L50 = getElement(y, L50c), gamma = getElement(y, gammac), MoreArgs = list(Len = Len))
do.call(rbind, res)
}
get_matrix <- function(x, Len, L50c, gammac) {
res <- lapply(x, map_fn, Len = Len, L50c = L50c, gammac = gammac)
do.call(rbind, res)
}
GN_mat <- get_matrix(mcmc_samps, Len = Length_bin, L50c = "GN_SL50", gammac = "GN_gamma")
GN <- colMeans(GN_mat)
ang_mat <- get_matrix(mcmc_samps, Len = Length_bin, L50c = "angler_SL50", gammac = "angler_gamma")
ang <- colMeans(ang_mat)
}
lines(1:length(Length_bin) - 0.5, GN, lwd = 3)
lines(1:length(Length_bin) - 0.5, ang, lwd = 3, lty = 3)
legend("bottomright", legend = c("Gillnet", "Angler"), lty = c(1, 3), lwd = 2)
box()
return(invisible())
}
plot_F_diagnostic <- function(RBfit) {
plot(RBfit@report$F_vec, typ = "o", xlab = "Iteration", ylab = "F", pch = 16, lwd = 2)
}
plot_pars <- function(RBdata = NULL, RBfit = NULL, stan_obj = NULL, stan_prior = NULL, plot.title = "Parameters",
plot_type = c("analytical_prior", "posterior_mode", "MCMC", "MCMC_both")) {
plot_type <- match.arg(plot_type)
prior_names <- substring(names(default_prior), 7)
if(plot_type == "posterior_mode") {
SD <- summary(RBfit@SD)
if(any(is.nan(SD))) return(invisible())
}
if(grepl("MCMC", plot_type)) {
sim <- stan_obj@sim
ind <- 1:(sim$warmup %/% sim$thin)
mcmc_samps <- lapply(sim$samples, function(x) lapply(x, `[`, -ind))
}
if(plot_type == "MCMC_both") {
sim2 <- stan_prior@sim
ind <- 1:(sim2$warmup %/% sim2$thin)
mcmc_prior_samps <- lapply(sim2$samples, function(x) lapply(x, `[`, -ind))
}
par(mfrow = c(4, 3), mar = c(4, 3, 1, 1), oma = c(ifelse(is.null(RBfit) & is.null(stan_obj), 0, 2), 3, 3, 0))
for(i in 1:length(prior_names)) {
# Priors
x_min <- 0
x_max <- 1e-3
if(plot_type == "analytical_prior" || plot_type == "posterior_mode" || plot_type == "MCMC") {
prior_par <- slot(RBdata, paste0("prior_", prior_names[i]))
x_min <- max(0, prior_par[1] - 2 * prior_par[2])
x_max <- prior_par[1] + 2 * prior_par[2]
} else if(plot_type == "MCMC_both") {
dens_prior <- lapply(mcmc_prior_samps, getElement, prior_names[i])
dens_prior <- do.call(c, dens_prior)
get_dens_prior <- density(dens_prior, from = min(dens_prior), to = max(dens_prior))
prior_par <- c(mean(dens_prior), sd(dens_prior))
x_min <- min(0, min(dens_prior))
x_max <- max(dens_prior)
}
# Posteriors
if(plot_type == "posterior_mode") {
post_par <- SD[match(prior_names[i], rownames(SD)), ]
x_min_post <- max(0, post_par[1] - 2 * post_par[2])
x_max_post <- post_par[1] + 2 * post_par[2]
x_min <- min(x_min, x_min_post)
x_max <- max(x_max, x_max_post)
}
if(grepl("MCMC", plot_type)) {
dens <- lapply(mcmc_samps, getElement, prior_names[i])
dens <- do.call(c, dens)
get_dens <- density(dens, from = min(dens), to = max(dens))
post_par <- c(mean(dens), sd(dens))
x_min <- min(x_min, min(dens))
x_max <- max(x_max, max(dens))
}
# Find appropriate limits for x-axis
if(x_min > x_max) x_min <- 0.2 * x_max
if((plot_type == "posterior_mode" | plot_type == "MCMC_both") && x_max > 20 * max(prior_par[1], post_par[1])) {
x_max <- 20 * max(prior_par[1], post_par[1])
}
# Get probability density for prior values of x-axis
if(plot_type == "analytical_prior" | plot_type == "posterior_mode") {
x_vec <- seq(x_min, x_max, length.out = 100)
prior_par2 <- lognormal_par(prior_par)
y_vec <- dlnorm(x_vec, prior_par2[1], prior_par2[2])
}
####### Make plot
plot(NULL, NULL, xlab = prior_names[i], ylab = "", typ = "n", yaxp = c(0, 1, 2), xlim = c(x_min, x_max), ylim = c(0, 1))
abline(h = 0, col = "grey")
# Plot prior
if(!grepl("MCMC", plot_type)) {
lines(x_vec, y_vec/max(y_vec), lwd = 2)
abline(v = prior_par[1], lwd = 2, lty = 2)
}
if(plot_type == "MCMC_both") {
lines(get_dens_prior$x, get_dens_prior$y/max(get_dens_prior$y), lwd = 2)
abline(v = mean(dens_prior), lwd = 2, lty = 2)
}
# Plot posterior
if(plot_type == "posterior_mode") {
y_vec_post <- dnorm(x_vec, post_par[1], post_par[2])
lines(x_vec, y_vec_post/max(y_vec_post), lwd = 2, col = "red")
abline(v = post_par[1], lwd = 2, lty = 2, col = "red")
} else if(grepl("MCMC", plot_type)) {
lines(get_dens$x, get_dens$y/max(get_dens$y), lwd = 2, col = "red")
abline(v = mean(dens), lwd = 2, lty = 2, col = "red")
}
# Plot legend
if(plot_type == "analytical_prior") {
legend("topright", legend = c(paste("Mean =", round(prior_par[1], 2)), paste("SD =", round(prior_par[2], 2))))
}
}
############ F and p_harvest plots
if(plot_type != "analytical_prior") {
par_vec <- c("F", "p_harvest")
for(i in 1:length(par_vec)) {
# Prior
if(plot_type == "MCMC_both") {
dens_prior <- lapply(mcmc_prior_samps, getElement, par_vec[i])
dens_prior <- do.call(c, dens_prior)
get_dens_prior <- density(dens_prior, from = min(dens_prior), to = max(dens_prior))
prior_par <- c(mean(dens_prior), sd(dens_prior))
x_min <- min(dens_prior)
x_max <- max(dens_prior)
}
# posterior
if(plot_type == "posterior_mode") {
post_par <- SD[match(par_vec[i], rownames(SD)), ]
x_min <- max(0.01, post_par[1] - 2 * post_par[2])
x_max <- post_par[1] + 2 * post_par[2]
if(x_min > x_max) x_min <- 0.2 * x_max
x_vec <- seq(x_min, x_max, length.out = 100)
y_vec_post <- dnorm(x_vec, post_par[1], post_par[2])
} else {
dens <- lapply(mcmc_samps, getElement, par_vec[i])
dens <- do.call(c, dens)
get_dens <- density(dens, from = min(dens), to = max(dens))
post_par <- c(mean(dens), sd(dens))
x_min <- min(dens)
x_max <- max(dens)
if(x_max > 20 * post_par[1]) x_max <- 20 * post_par[1]
x_vec <- get_dens$x
y_vec_post <- get_dens$y
}
plot(NULL, NULL, xlab = par_vec[i], ylab = "", typ = "n", yaxp = c(0, 1, 2),
xlim = c(x_min, x_max), ylim = c(0, 1))
abline(h = 0, col = "grey")
# Plot prior
if(plot_type == "MCMC_both") {
lines(get_dens_prior$x, get_dens_prior$y/max(get_dens_prior$y), lwd = 2)
abline(v = prior_par[1], lwd = 2, lty = 2)
}
# Plot posterior
lines(x_vec, y_vec_post/max(y_vec_post), lwd = 2, col = "red")
abline(v = post_par[1], lwd = 2, lty = 2, col = "red")
}
}
mtext(plot.title, outer = TRUE, side = 3, font = 2)
mtext("Relative density", outer = TRUE, side = 2)
if(plot_type == "posterior_mode" || plot_type == "MCMC_both") {
par(fig = c(0, 1, 0, 1), oma = c(0, 0, 0, 0), mar = c(0, 0, 0, 0), new = TRUE)
plot(0, 0, type = "n", bty = "n", xaxt = "n", yaxt = "n")
legend("bottom", legend = c("Prior", "Posterior"), col = c("black", "red"), lwd = 2, bty = "n", horiz = TRUE)
}
invisible()
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.