Skip to content
Snippets Groups Projects
Commit c074b343 authored by Sebastian Henz's avatar Sebastian Henz
Browse files

Plot more stresses and effects. Closes #21 and fixes parts of #7

parent ca0f9003
No related branches found
No related tags found
1 merge request!19Develop
# stressaddition (development version) # stressaddition (development version)
* Added predict_mixture() for the prediction of the effects of mixtures of two toxicants. * The functions `plot_effect()` and `plot_stress()` gain a `which` argument that controls which curves are plotted. Consequently, the `show_LL5_model` argument of `plot_effect()` was removed.
* Fixed documentation of `ecxsys()` and `predict_ecxsys`. * Added arguments `xlab` and `ylab` to `plot_stress`.
* Changed some colors of the stress curves so they better match with the colors of related effect curves.
* Added `predict_mixture()` for the prediction of the effects of mixtures of two toxicants.
* Fixed documentation of `ecxsys()` and `predict_ecxsys()`.
# stressaddition 2.0.0 # stressaddition 2.0.0
......
...@@ -33,12 +33,12 @@ get_log_ticks <- function(x) { ...@@ -33,12 +33,12 @@ get_log_ticks <- function(x) {
} }
adjust_smooth_concentrations <- function(curves, conc_adjust_factor) { adjust_smooth_concentrations <- function(model) {
# Helper for the plot functions, not exported. # Helper for the plot functions, not exported.
# Deals with the concentrations which are unnecessary for plotting. # Deals with the concentrations which are unnecessary for plotting.
# This means it removes the concentrations in the gap and scales the # This means it removes the concentrations in the gap and scales the
# concentrations left of the gap up. # concentrations left of the gap up.
curves <- model$curves
gap_idx <- min(which(!curves$use_for_plotting)) gap_idx <- min(which(!curves$use_for_plotting))
# Keep only the values to the left and right of the axis break: # Keep only the values to the left and right of the axis break:
...@@ -50,7 +50,7 @@ adjust_smooth_concentrations <- function(curves, conc_adjust_factor) { ...@@ -50,7 +50,7 @@ adjust_smooth_concentrations <- function(curves, conc_adjust_factor) {
# Shift the small concentrations upwards so the plot has a nice x-axis: # Shift the small concentrations upwards so the plot has a nice x-axis:
curves$concentration[1:gap_idx] <- curves$concentration[1:gap_idx] <-
curves$concentration[1:gap_idx] / conc_adjust_factor curves$concentration[1:gap_idx] / model$conc_adjust_factor
list( list(
curves = curves, curves = curves,
......
...@@ -3,16 +3,18 @@ ...@@ -3,16 +3,18 @@
#' Plot the results of the ECx-SyS model #' Plot the results of the ECx-SyS model
#' #'
#' Convenience functions to plot the observed and modeled effect and the #' Plot the observed and modeled effects and stresses.
#' system stress with and without environmental stress.
#' #'
#' @name plot_ecxsys #' @name plot_ecxsys
#' #'
#' @param model The list returned from \code{\link{ecxsys}}. #' @param model The list returned from \code{\link{ecxsys}}.
#' @param show_LL5_model Should the log-logistic models be plotted for #' @param which A vector of curve names to plot. Allowed values are the column
#' comparison? Defaults to \code{FALSE}. #' names of the \code{model$curves} data frame. The default \code{NULL} only
#' @param show_legend Should the plot include a legend? Defaults to FALSE #' plots the most important curves. Use \code{which = "all"} to display all
#' because it may cover some points or lines depending on the plot size. #' curves.
#' @param show_legend Should the plot include a legend? Defaults to \code{FALSE}
#' because it may cover some parts of the plot depending on the plot size and
#' the number of elements shown.
#' @param xlab,ylab Axis labels. #' @param xlab,ylab Axis labels.
#' #'
#' @examples model <- ecxsys( #' @examples model <- ecxsys(
...@@ -23,4 +25,8 @@ ...@@ -23,4 +25,8 @@
#' ) #' )
#' plot_effect(model) #' plot_effect(model)
#' plot_stress(model) #' plot_stress(model)
#'
#' # Plot all curves:
#' plot_effect(model, which = "all")
#' plot_stress(model, which = "all")
NULL NULL
...@@ -2,33 +2,47 @@ ...@@ -2,33 +2,47 @@
#' @export #' @export
plot_effect <- function(model, plot_effect <- function(model,
which = NULL, which = NULL,
show_observed = TRUE,
show_legend = FALSE, show_legend = FALSE,
xlab = "concentration", xlab = "concentration",
ylab = "effect") { ylab = "effect") {
stopifnot(inherits(model, "ecxsys")) stopifnot(inherits(model, "ecxsys"))
curve_names <- names(model$curves) curve_names <- names(model$curves)
valid_names <- curve_names[startsWith(curve_names, "effect")] valid_names <- curve_names[startsWith(curve_names, "effect")]
if (is.null(which)) { if (is.null(which)) {
which <- c("effect_tox_sys", "effect_tox_env_sys") which <- c("effect_tox_sys")
} else if (length(which) == 1 && which == "all") { if (model$with_env) {
which <- valid_names which <- c(which, "effect_tox_env_sys")
}
} else if ("all" %in% which) {
if (length(which) == 1) {
which <- valid_names
} else {
stop("'all' must not be combined with other curve names.")
}
} else if (!all(which %in% valid_names)) { } else if (!all(which %in% valid_names)) {
stop("Argument 'which' contains invalid names. Only effects are allowed.") warning("Argument 'which' contains invalid names.")
} if (!model$with_env && any(grepl("env", which, fixed = TRUE))) {
if (!model$with_env && any(grepl("env", which, fixed = TRUE))) { warning("'which' contains names with 'env' but the model was",
warning("'which' contains names with 'env' but the model was built ", " built without environmental effects.")
"without environmental effects.") }
which <- which[which %in% valid_names]
} }
temp <- adjust_smooth_concentrations( temp <- adjust_smooth_concentrations(model)
model$curves,
model$conc_adjust_factor
)
curves <- temp$curves curves <- temp$curves
log_ticks <- get_log_ticks(curves$concentration) log_ticks <- get_log_ticks(curves$concentration)
concentration <- c(curves$concentration[1], model$args$concentration[-1]) concentration <- c(curves$concentration[1], model$args$concentration[-1])
legend_df <- data.frame(
text = character(),
pch = numeric(),
lty = numeric(),
col = character(),
order = numeric(), # controls sorting of legend elements
stringsAsFactors = FALSE
)
plot( plot(
NA, NA,
NA, NA,
...@@ -42,37 +56,31 @@ plot_effect <- function(model, ...@@ -42,37 +56,31 @@ plot_effect <- function(model,
las = 1 las = 1
) )
if (show_observed) { points(
concentration,
model$args$effect_tox_observed,
pch = 16,
col = "blue"
)
legend_df[nrow(legend_df) + 1, ] <- list("tox (observed)", 16, 0, "blue", 1)
if (model$with_env) {
points( points(
concentration, concentration,
model$args$effect_tox_observed, model$args$effect_tox_env_observed,
pch = 16, pch = 16,
col = "blue" col = "red"
)
if (model$with_env) {
points(
concentration,
model$args$effect_tox_env_observed,
pch = 16,
col = "red"
)
}
}
if ("effect_tox_LL5" %in% which) {
lines(
curves$concentration,
curves$effect_tox_LL5,
col = "darkblue",
lty = 4
) )
legend_df[nrow(legend_df) + 1, ] <- list("tox + env (observed)", 16, 0, "red", 2)
} }
# The lines are drawn in this order to ensure that dotted and dashed lines
# are on top of solid lines for better visibility.
if ("effect_tox_sys" %in% which) { if ("effect_tox_sys" %in% which) {
lines( lines(
curves$concentration, curves$concentration,
curves$effect_tox_sys, curves$effect_tox_sys,
col = "blue" col = "blue"
) )
legend_df[nrow(legend_df) + 1, ] <- list("tox + sys", NA, 1, "blue", 5)
} }
if ("effect_tox" %in% which) { if ("effect_tox" %in% which) {
lines( lines(
...@@ -81,22 +89,25 @@ plot_effect <- function(model, ...@@ -81,22 +89,25 @@ plot_effect <- function(model,
col = "deepskyblue", col = "deepskyblue",
lty = 2 lty = 2
) )
legend_df[nrow(legend_df) + 1, ] <- list("tox", NA, 2, "deepskyblue", 4)
}
if ("effect_tox_LL5" %in% which) {
lines(
curves$concentration,
curves$effect_tox_LL5,
col = "darkblue",
lty = 3
)
legend_df[nrow(legend_df) + 1, ] <- list("tox (LL5)", NA, 3, "darkblue", 3)
} }
if (model$with_env) { if (model$with_env) {
if ("effect_tox_env_LL5" %in% which) {
lines(
curves$concentration,
curves$effect_tox_env_LL5,
col = "darkred",
lty = 4
)
}
if ("effect_tox_env_sys" %in% which) { if ("effect_tox_env_sys" %in% which) {
lines( lines(
curves$concentration, curves$concentration,
curves$effect_tox_env_sys, curves$effect_tox_env_sys,
col = "red" col = "red"
) )
legend_df[nrow(legend_df) + 1, ] <- list("tox + env + sys", NA, 1, "red", 8)
} }
if ("effect_tox_env" %in% which) { if ("effect_tox_env" %in% which) {
lines( lines(
...@@ -105,6 +116,16 @@ plot_effect <- function(model, ...@@ -105,6 +116,16 @@ plot_effect <- function(model,
col = "orange", col = "orange",
lty = 2 lty = 2
) )
legend_df[nrow(legend_df) + 1, ] <- list("tox + env", NA, 2, "orange", 7)
}
if ("effect_tox_env_LL5" %in% which) {
lines(
curves$concentration,
curves$effect_tox_env_LL5,
col = "darkred",
lty = 3
)
legend_df[nrow(legend_df) + 1, ] <- list("tox + env (LL5)", NA, 3, "darkred", 6)
} }
} }
...@@ -113,28 +134,13 @@ plot_effect <- function(model, ...@@ -113,28 +134,13 @@ plot_effect <- function(model,
plotrix::axis.break(1, breakpos = temp$axis_break_conc) plotrix::axis.break(1, breakpos = temp$axis_break_conc)
if (show_legend) { if (show_legend) {
legend_text <- c("tox", "tox + sys") legend_df <- legend_df[order(legend_df$order), ]
legend_pch <- c(NA, 16)
legend_lty <- c(2, 1)
legend_col <- c("deepskyblue", "blue")
if (model$with_env) {
legend_text <- c(legend_text, "tox + env", "tox + env + sys")
legend_pch <- c(legend_pch, NA, 16)
legend_lty <- c(legend_lty, 2, 1)
legend_col <- c(legend_col, "orange", "red")
}
if (show_LL5_model) {
legend_text <- c(legend_text, "tox (LL5)", "tox + env (LL5)")
legend_pch <- c(legend_pch, NA, NA)
legend_lty <- c(legend_lty, 4, 4)
legend_col <- c(legend_col, "darkblue", "darkred")
}
legend( legend(
"topright", "topright",
legend = legend_text, legend = legend_df$text,
pch = legend_pch, pch = legend_df$pch,
lty = legend_lty, lty = legend_df$lty,
col = legend_col col = legend_df$col
) )
} }
} }
#' @rdname plot_ecxsys #' @rdname plot_ecxsys
#' @export #' @export
plot_stress <- function(model, show_legend = FALSE) { plot_stress <- function(model,
which = NULL,
show_legend = FALSE,
xlab = "concentration",
ylab = "stress") {
stopifnot(inherits(model, "ecxsys")) stopifnot(inherits(model, "ecxsys"))
temp <- adjust_smooth_concentrations(
model$curves, curve_names <- names(model$curves)
model$conc_adjust_factor valid_names <- curve_names[
) startsWith(curve_names, "stress") | startsWith(curve_names, "sys")
]
if (is.null(which)) {
which <- c("sys_tox")
if (model$with_env) {
which <- c(which, "sys_tox_env")
}
} else if ("all" %in% which) {
if (length(which) == 1) {
which <- valid_names
} else {
stop("'all' must not be combined with other curve names.")
}
} else if (!all(which %in% valid_names)) {
warning("Argument 'which' contains invalid names.")
if (!model$with_env && any(grepl("env", which, fixed = TRUE))) {
warning("'which' contains names with 'env' but the model was",
" built without environmental effects.")
}
which <- which[which %in% valid_names]
if (length(which) == 0) {
stop("No curves to display.")
}
}
temp <- adjust_smooth_concentrations(model)
curves <- temp$curves curves <- temp$curves
axis_break_conc <- temp$axis_break_conc axis_break_conc <- temp$axis_break_conc
log_ticks <- get_log_ticks(curves$concentration) log_ticks <- get_log_ticks(curves$concentration)
concentration <- c(curves$concentration[1], model$args$concentration[-1]) concentration <- c(curves$concentration[1], model$args$concentration[-1])
legend_df <- data.frame(
text = character(),
pch = numeric(),
lty = numeric(),
col = character(),
order = numeric(), # controls sorting of legend elements
stringsAsFactors = FALSE
)
plot( plot(
NA, NA,
NA, NA,
xlim = range(curves$concentration, na.rm = TRUE), xlim = range(curves$concentration, na.rm = TRUE),
ylim = c(0, 1), ylim = c(0, max(curves[, which], 1, na.rm = TRUE)),
log = "x", log = "x",
xlab = "concentration", xlab = xlab,
ylab = "system stress", ylab = ylab,
xaxt = "n", xaxt = "n",
las = 1, las = 1,
bty = "L" bty = "L"
) )
lines( # The lines are drawn in this order to ensure that dotted and dashed lines
curves$concentration, # are on top of solid lines for better visibility.
curves$sys_tox, if ("stress_tox_sys" %in% which) {
col = "blue" lines(
) curves$concentration,
points( curves$stress_tox_sys,
concentration, col = "blue"
model$sys_tox_not_fitted, )
pch = 16, legend_df[nrow(legend_df) + 1, ] <- list("tox + sys", NA, 1, "blue", 3)
col = "blue" }
) if ("stress_tox" %in% which) {
if (model$with_env) {
lines( lines(
curves$concentration, curves$concentration,
curves$sys_tox_env, curves$stress_tox,
col = "red" col = "deepskyblue",
lty = 2
) )
legend_df[nrow(legend_df) + 1, ] <- list("tox", NA, 2, "deepskyblue", 1)
}
if ("sys_tox" %in% which) {
points( points(
concentration, concentration,
model$sys_tox_env_not_fitted, model$sys_tox_not_fitted,
pch = 16, pch = 16,
col = "red" col = "steelblue3"
) )
lines(
curves$concentration,
curves$sys_tox,
col = "steelblue3"
)
legend_df[nrow(legend_df) + 1, ] <- list("sys (tox)", 16, 1, "steelblue3", 2)
}
if (model$with_env) {
if ("stress_tox_env_sys" %in% which) {
lines(
curves$concentration,
curves$stress_tox_env_sys,
col = "red"
)
legend_df[nrow(legend_df) + 1, ] <- list("tox + env + sys", NA, 1, "red", 7)
}
if ("stress_env" %in% which) {
lines(
curves$concentration,
curves$stress_env,
col = "forestgreen",
lty = 3
)
legend_df[nrow(legend_df) + 1, ] <- list("env", NA, 3, "forestgreen", 4)
}
if ("stress_tox_env" %in% which) {
lines(
curves$concentration,
curves$stress_tox_env,
col = "orange",
lty = 2
)
legend_df[nrow(legend_df) + 1, ] <- list("tox + env", NA, 2, "orange", 5)
}
if ("sys_tox_env" %in% which) {
points(
concentration,
model$sys_tox_env_not_fitted,
pch = 16,
col = "violetred"
)
lines(
curves$concentration,
curves$sys_tox_env,
col = "violetred"
)
legend_df[nrow(legend_df) + 1, ] <- list("sys (tox + env)", 16, 1, "violetred", 6)
}
} }
axis(1, at = log_ticks$major, labels = log_ticks$major_labels) axis(1, at = log_ticks$major, labels = log_ticks$major_labels)
...@@ -55,18 +143,13 @@ plot_stress <- function(model, show_legend = FALSE) { ...@@ -55,18 +143,13 @@ plot_stress <- function(model, show_legend = FALSE) {
plotrix::axis.break(1, breakpos = axis_break_conc) plotrix::axis.break(1, breakpos = axis_break_conc)
if (show_legend) { if (show_legend) {
legend_text <- c("tox") legend_df <- legend_df[order(legend_df$order), ]
legend_col <- c("blue")
if (model$with_env) {
legend_text <- c(legend_text, "tox + env")
legend_col <- c(legend_col, "red")
}
legend( legend(
"topright", "topright",
legend = legend_text, legend = legend_df$text,
col = legend_col, pch = legend_df$pch,
pch = 16, lty = legend_df$lty,
lty = 1 col = legend_df$col
) )
} }
} }
...@@ -10,7 +10,7 @@ plot_effect( ...@@ -10,7 +10,7 @@ plot_effect(
model, model,
which = NULL, which = NULL,
show_observed = TRUE, show_observed = TRUE,
show_legend = FALSE, show_legend = TRUE,
xlab = "concentration", xlab = "concentration",
ylab = "effect" ylab = "effect"
) )
...@@ -20,17 +20,20 @@ plot_stress(model, show_legend = FALSE) ...@@ -20,17 +20,20 @@ plot_stress(model, show_legend = FALSE)
\arguments{ \arguments{
\item{model}{The list returned from \code{\link{ecxsys}}.} \item{model}{The list returned from \code{\link{ecxsys}}.}
\item{show_legend}{Should the plot include a legend? Defaults to FALSE \item{which}{A vector of curve names to plot. Allowed values are the column
because it may cover some points or lines depending on the plot size.} names of the \code{model$curves} data frame. The default \code{NULL} only
plots the most important curves. Use \code{which = "all"} to display all
curves.}
\item{xlab, ylab}{Axis labels.} \item{show_observed}{Should the observed values be plotted as points?}
\item{show_legend}{Should the plot include a legend? May cover some parts of
the plot depending on the plot size and the number of elements shown.}
\item{show_LL5_model}{Should the log-logistic models be plotted for \item{xlab, ylab}{Axis labels.}
comparison? Defaults to \code{FALSE}.}
} }
\description{ \description{
Convenience functions to plot the observed and modeled effect and the Plot the observed and modeled effects and stresses.
system stress with and without environmental stress.
} }
\examples{ \examples{
model <- ecxsys( model <- ecxsys(
...@@ -41,4 +44,8 @@ model <- ecxsys( ...@@ -41,4 +44,8 @@ model <- ecxsys(
) )
plot_effect(model) plot_effect(model)
plot_stress(model) plot_stress(model)
# Plot all curves:
plot_effect(model, which = "all")
plot_stress(model, which = "all")
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment