Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ individual variability in growth to be modelled.
- `plotSpectra()` now accepts `log_x`, `log_y`, and `log` arguments for
controlling axis scaling, matching the mizer array `plot()` methods.

- Size-based plots now accept `size_axis = "l"` to show length in cm on the
size axis instead of weight in grams, using the species' allometric
weight-length relationship.

- Size-based plots with a `size_axis` argument now accept `llim`, the
length-axis equivalent of `wlim`, for filtering and limiting plots when
`size_axis = "l"`.

- The `plot()` and `summary()` methods for `MizerParams`, `MizerSim`, and the
mizer array classes are now registered as S3 methods rather than S4 methods,
so `plot()` and `summary()` remain plain S3 generics when mizer is loaded,
Expand Down
70 changes: 58 additions & 12 deletions R/ArraySpeciesBySize-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ print.summary.ArraySpeciesBySize <- function(x, ...) {
#' @param wlim A numeric vector of length two providing lower and upper limits
#' for the weight (x) axis. Use `NA` to refer to the existing minimum or
#' maximum. Only applies to `ArraySpeciesBySize`.
#' @param llim A numeric vector of length two providing lower and upper limits
#' for the length (x) axis when `size_axis = "l"`. Use `NA` to refer to the
#' existing minimum or maximum. Only applies to `ArraySpeciesBySize`.
#' @param size_axis Whether to plot size as weight (`"w"`, default) or length
#' (`"l"`), using the allometric weight-length relationship.
#' @param ylim A numeric vector of length two providing lower and upper limits
#' for the value (y) axis. Use `NA` to refer to the existing minimum or
#' maximum.
Expand All @@ -180,24 +185,36 @@ print.summary.ArraySpeciesBySize <- function(x, ...) {
#' \donttest{
#' plot(getEncounter(NS_params))
#' plot(getFeedingLevel(NS_params), species = c("Cod", "Herring"))
#' plot(getPredMort(NS_params), species = c("Cod", "Herring"),
#' size_axis = "l")
#' }
plot.ArraySpeciesBySize <- function(x, species = NULL,
all.sizes = FALSE, highlight = NULL,
return_data = FALSE, log_x = TRUE, log_y = FALSE,
log = NULL,
wlim = c(NA, NA), ylim = c(NA, NA),
wlim = c(NA, NA), llim = c(NA, NA),
ylim = c(NA, NA),
size_axis = c("w", "l"),
total = FALSE, background = TRUE,
y_ticks = 6, ...) {
size_axis <- plot_size_axis(size_axis)
log_axes <- parsePlotLog(log, log_x = log_x, log_y = log_y)
log_x <- log_axes$log_x
log_y <- log_axes$log_y

assert_that(length(wlim) == 2,
length(llim) == 2,
length(ylim) == 2)
value_name <- attr(x, "value_name") %||% "Rate"
units_str <- attr(x, "units")
params <- attr(x, "params")
plot_dat <- prepare_ArraySpeciesBySize_plot_data(
x, species = species, all.sizes = all.sizes, wlim = wlim,
total = total, background = background)
plot_dat <- convert_plot_size_axis(plot_dat, params, size_axis)
if (identical(size_axis, "l")) {
plot_dat <- filter_plot_length_limits(plot_dat, llim)
}

if (return_data) return(plot_dat)

Expand All @@ -206,11 +223,13 @@ plot.ArraySpeciesBySize <- function(x, species = NULL,
y_label <- paste0(value_name, " [", units_str, "]")
}

plotDataFrame(plot_dat, params, xlab = "Size [g]", ylab = y_label,
plotDataFrame(plot_dat, params, xlab = plot_size_xlab(size_axis),
ylab = y_label,
xtrans = if (log_x) "log10" else "identity",
ytrans = if (log_y) "log10" else "identity",
xlim = wlim, ylim = ylim, highlight = highlight,
y_ticks = y_ticks, legend_var = "Legend")
xlim = plot_size_xlim(wlim, size_axis, llim), ylim = ylim,
highlight = highlight, y_ticks = y_ticks,
legend_var = "Legend")
}

parsePlotLog <- function(log, log_x = FALSE, log_y = FALSE) {
Expand Down Expand Up @@ -257,14 +276,20 @@ plot2 <- function(x, y, ...) {
plot2.ArraySpeciesBySize <- function(x, y, name1 = "First", name2 = "Second",
species = NULL, all.sizes = FALSE,
log_x = TRUE, log_y = FALSE, log = NULL,
wlim = c(NA, NA), ylim = c(NA, NA),
wlim = c(NA, NA), llim = c(NA, NA),
ylim = c(NA, NA),
size_axis = c("w", "l"),
total = FALSE, background = TRUE,
y_ticks = 6, ...) {
check_plot2_compatible(x, y, "ArraySpeciesBySize")
compare_array_metadata(x, y)
size_axis <- plot_size_axis(size_axis)
log_axes <- parsePlotLog(log, log_x = log_x, log_y = log_y)
log_x <- log_axes$log_x
log_y <- log_axes$log_y
assert_that(length(wlim) == 2,
length(llim) == 2,
length(ylim) == 2)

params <- attr(x, "params")
y_label <- array_y_label(x, default = "Rate")
Expand All @@ -277,11 +302,13 @@ plot2.ArraySpeciesBySize <- function(x, y, name1 = "First", name2 = "Second",

plotComparisonDataFrame(plot_dat1, plot_dat2, params,
name1 = name1, name2 = name2,
xlab = "Size [g]", ylab = y_label,
xlab = plot_size_xlab(size_axis), ylab = y_label,
xtrans = if (log_x) "log10" else "identity",
ytrans = if (log_y) "log10" else "identity",
xlim = wlim, ylim = ylim,
y_ticks = y_ticks, legend_var = "Legend")
xlim = plot_size_xlim(wlim, size_axis, llim),
ylim = ylim,
y_ticks = y_ticks, legend_var = "Legend",
size_axis = size_axis)
}

#' Plot the relative difference between two mizer array objects
Expand Down Expand Up @@ -315,11 +342,17 @@ plotRelative.ArraySpeciesBySize <- function(x, y, species = NULL,
all.sizes = FALSE,
log_x = TRUE,
wlim = c(NA, NA),
llim = c(NA, NA),
ylim = c(NA, NA),
size_axis = c("w", "l"),
total = FALSE,
background = TRUE, ...) {
check_plot2_compatible(x, y, "ArraySpeciesBySize")
compare_array_metadata(x, y)
size_axis <- plot_size_axis(size_axis)
assert_that(length(wlim) == 2,
length(llim) == 2,
length(ylim) == 2)
params <- attr(x, "params")
plot_dat1 <- prepare_ArraySpeciesBySize_plot_data(
x, species = species, all.sizes = all.sizes, wlim = wlim,
Expand All @@ -329,9 +362,11 @@ plotRelative.ArraySpeciesBySize <- function(x, y, species = NULL,
total = total, background = background)

plotRelativeDataFrame(plot_dat1, plot_dat2, params,
xlab = "Size [g]",
xlab = plot_size_xlab(size_axis),
xtrans = if (log_x) "log10" else "identity",
xlim = wlim, ylim = ylim, legend_var = "Legend")
xlim = plot_size_xlim(wlim, size_axis, llim),
ylim = ylim,
legend_var = "Legend", size_axis = size_axis)
}

check_plot2_compatible <- function(x, y, class) {
Expand Down Expand Up @@ -405,6 +440,8 @@ addPlot <- function(plot, x, ...) {
addPlot.ArraySpeciesBySize <- function(plot, x, species = NULL,
all.sizes = FALSE,
wlim = c(NA, NA),
llim = c(NA, NA),
size_axis = c("w", "l"),
total = FALSE,
background = TRUE,
colour = NULL,
Expand All @@ -419,15 +456,24 @@ addPlot.ArraySpeciesBySize <- function(plot, x, species = NULL,
is.number(alpha),
alpha >= 0,
alpha <= 1)
size_axis <- plot_size_axis(size_axis)
assert_that(length(wlim) == 2,
length(llim) == 2)

plot <- deep_copy(plot)
plot_dat <- prepare_ArraySpeciesBySize_plot_data(
x, species = species, all.sizes = all.sizes, wlim = wlim,
total = total, background = background)
check_addPlot_compatible(plot, x_var = "w", y_var = "value",
params <- attr(x, "params")
plot_dat <- convert_plot_size_axis(plot_dat, params, size_axis)
if (identical(size_axis, "l")) {
plot_dat <- filter_plot_length_limits(plot_dat, llim)
}
x_var <- plot_size_x_var(size_axis)
check_addPlot_compatible(plot, x_var = x_var, y_var = "value",
units = attr(x, "units"))

mapping <- aes(x = .data[["w"]], y = .data[["value"]],
mapping <- aes(x = .data[[x_var]], y = .data[["value"]],
group = .data[["Species"]])
if (is.null(colour)) {
mapping$colour <- rlang::quo(.data[["Legend"]])
Expand Down
33 changes: 25 additions & 8 deletions R/ArrayTimeBySpeciesBySize-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ plot.ArrayTimeBySpeciesBySize <- function(x, species = NULL, time = NULL,
all.sizes = FALSE, highlight = NULL,
return_data = FALSE, log_x = TRUE,
log_y = FALSE, log = NULL,
wlim = c(NA, NA), ylim = c(NA, NA),
wlim = c(NA, NA), llim = c(NA, NA),
ylim = c(NA, NA),
size_axis = c("w", "l"),
total = FALSE, background = TRUE,
y_ticks = 6, ...) {
params <- attr(x, "params")
Expand All @@ -167,8 +169,10 @@ plot.ArrayTimeBySpeciesBySize <- function(x, species = NULL, time = NULL,
plot.ArraySpeciesBySize(slice, species = species, all.sizes = all.sizes,
highlight = highlight, return_data = return_data,
log_x = log_x, log_y = log_y, log = log,
wlim = wlim, ylim = ylim, total = total,
background = background, y_ticks = y_ticks, ...)
wlim = wlim, ylim = ylim, llim = llim,
size_axis = size_axis,
total = total, background = background,
y_ticks = y_ticks, ...)
}

#' @rdname plot2
Expand All @@ -183,7 +187,9 @@ plot2.ArrayTimeBySpeciesBySize <- function(x, y, name1 = "First",
log_x = TRUE, log_y = FALSE,
log = NULL,
wlim = c(NA, NA),
llim = c(NA, NA),
ylim = c(NA, NA),
size_axis = c("w", "l"),
total = FALSE,
background = TRUE,
y_ticks = 6, ...) {
Expand All @@ -194,7 +200,8 @@ plot2.ArrayTimeBySpeciesBySize <- function(x, y, name1 = "First",
plot2.ArraySpeciesBySize(slice1, slice2, name1 = name1, name2 = name2,
species = species, all.sizes = all.sizes,
log_x = log_x, log_y = log_y, log = log,
wlim = wlim, ylim = ylim, total = total,
wlim = wlim, ylim = ylim, llim = llim,
size_axis = size_axis, total = total,
background = background, y_ticks = y_ticks, ...)
}

Expand All @@ -208,7 +215,9 @@ plotRelative.ArrayTimeBySpeciesBySize <- function(x, y, species = NULL,
all.sizes = FALSE,
log_x = TRUE,
wlim = c(NA, NA),
llim = c(NA, NA),
ylim = c(NA, NA),
size_axis = c("w", "l"),
total = FALSE,
background = TRUE, ...) {
check_plot2_compatible(x, y, "ArrayTimeBySpeciesBySize")
Expand All @@ -217,7 +226,8 @@ plotRelative.ArrayTimeBySpeciesBySize <- function(x, y, species = NULL,

plotRelative.ArraySpeciesBySize(slice1, slice2, species = species,
all.sizes = all.sizes, log_x = log_x,
wlim = wlim, ylim = ylim,
wlim = wlim, ylim = ylim, llim = llim,
size_axis = size_axis,
total = total, background = background,
...)
}
Expand Down Expand Up @@ -267,8 +277,10 @@ animate.ArrayTimeBySpeciesBySize <- function(x, species = NULL,
time_range = NULL,
log_x = TRUE,
wlim = c(NA, NA),
llim = c(NA, NA),
ylim = c(NA, NA),
log_y = TRUE,
size_axis = c("w", "l"),
total = FALSE,
background = TRUE,
frame_duration = 500,
Expand All @@ -279,7 +291,8 @@ animate.ArrayTimeBySpeciesBySize <- function(x, species = NULL,
is.number(frame_duration), frame_duration >= 0,
is.number(transition_duration), transition_duration >= 0,
is.string(easing),
length(wlim) == 2, length(ylim) == 2)
length(wlim) == 2, length(llim) == 2, length(ylim) == 2)
size_axis <- plot_size_axis(size_axis)

params <- attr(x, "params")
value_name <- attr(x, "value_name") %||% "Value"
Expand Down Expand Up @@ -349,8 +362,12 @@ animate.ArrayTimeBySpeciesBySize <- function(x, species = NULL,
y_label <- paste0(value_name, " [", units_str, "]")
}

animate_plotly(df, params, log_x, log_y, y_label, wlim, ylim,
frame_duration, transition_duration, easing)
animate_plotly(df, params, log_x, log_y, y_label, wlim, llim,
ylim,
size_axis = size_axis,
frame_duration = frame_duration,
transition_duration = transition_duration,
easing = easing)
}

#' @export
Expand Down
33 changes: 27 additions & 6 deletions R/animateSpectra.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#' range. Default is the entire time range of `x`.
#' @param log_x If `TRUE` (default), use a log10 x-axis for body size.
#' @param log_y If `TRUE` (default), use a log10 y-axis.
#' @param size_axis Whether to plot size as weight (`"w"`, default) or length
#' (`"l"`), using the allometric weight-length relationship.
#' @param total A boolean value that determines whether the total over all
#' selected species is plotted as an additional trace called `"Total"`.
#' Default is `FALSE`.
Expand All @@ -43,6 +45,9 @@
#' @param wlim A numeric vector of length two providing lower and upper limits
#' for the body-size (x) axis. Use `NA` to refer to the existing minimum or
#' maximum.
#' @param llim A numeric vector of length two providing lower and upper limits
#' for the length (x) axis when `size_axis = "l"`. Use `NA` to refer to the
#' existing minimum or maximum.
#' @param ylim A numeric vector of length two providing lower and upper limits
#' for the value (y) axis. Use `NA` to refer to the existing minimum or
#' maximum. Limits are applied as Plotly axis ranges, so points outside the
Expand Down Expand Up @@ -88,19 +93,23 @@ animate <- function(x, ...) UseMethod("animate")
#' @export
animate.MizerSim <- function(x, species = NULL, time_range = NULL,
log_x = TRUE, log_y = TRUE,
wlim = c(NA, NA), ylim = c(NA, NA),
wlim = c(NA, NA), llim = c(NA, NA),
ylim = c(NA, NA),
size_axis = c("w", "l"),
power = 1, total = FALSE, resource = TRUE,
background = TRUE,
frame_duration = 500,
transition_duration = frame_duration,
easing = "linear", ...) {
sim <- x
size_axis <- plot_size_axis(size_axis)
assert_that(is.flag(total), is.flag(resource), is.flag(background),
is.number(power),
is.number(frame_duration), frame_duration >= 0,
is.number(transition_duration), transition_duration >= 0,
is.string(easing),
length(wlim) == 2,
length(llim) == 2,
length(ylim) == 2)

species <- valid_species_arg(sim, species)
Expand Down Expand Up @@ -155,8 +164,12 @@ animate.MizerSim <- function(x, species = NULL, time_range = NULL,
}
nf <- mutate(nf, value = value * w^power)

animate_plotly(nf, sim@params, log_x, log_y, y_label, wlim, ylim,
frame_duration, transition_duration, easing)
animate_plotly(nf, sim@params, log_x, log_y, y_label, wlim, llim,
ylim,
size_axis = size_axis,
frame_duration = frame_duration,
transition_duration = transition_duration,
easing = easing)
}

# Build a plotly animation from a prepared long-format data frame.
Expand All @@ -165,9 +178,14 @@ animate.MizerSim <- function(x, species = NULL, time_range = NULL,
# by individual Species within each legend group — so background species always
# appear together and share a single legend entry.
animate_plotly <- function(df, params, log_x, log_y, y_label,
wlim = c(NA, NA), ylim = c(NA, NA),
wlim = c(NA, NA), llim = c(NA, NA),
ylim = c(NA, NA),
size_axis = "w",
frame_duration = 500, transition_duration = 500,
easing = "linear") {
size_axis <- plot_size_axis(size_axis)
df <- convert_plot_size_axis(df, params, size_axis)
x_var <- plot_size_x_var(size_axis)
legend_name_order <- intersect(names(params@linecolour),
unique(df$legend_name))
sp_order <- unlist(lapply(legend_name_order, function(ln) {
Expand All @@ -185,7 +203,7 @@ animate_plotly <- function(df, params, log_x, log_y, y_label,
p <- plotly::add_lines(
p,
data = df_sp,
x = ~w, y = ~value,
x = stats::as.formula(paste0("~", x_var)), y = ~value,
frame = ~time,
name = ln,
legendgroup = ln,
Expand All @@ -194,7 +212,10 @@ animate_plotly <- function(df, params, log_x, log_y, y_label,
)
}
p <- plotly::layout(p,
xaxis = plotly_axis(df$w, wlim, log_x, "Size [g]"),
xaxis = plotly_axis(
df[[x_var]],
plot_size_xlim(wlim, size_axis, llim),
log_x, plot_size_xlab(size_axis)),
yaxis = plotly_axis(df$value, ylim, log_y, y_label),
legend = list(traceorder = "normal"))
plotly::animation_opts(p, frame = frame_duration,
Expand Down
Loading
Loading