From 0287675f2f7d930006280a54be725049a8f8aea3 Mon Sep 17 00:00:00 2001 From: Lorenzo Gaborini Date: Mon, 3 Nov 2025 22:08:41 +0100 Subject: [PATCH 1/7] get_layer_data(), get_layer_grob() accept layer names --- R/plot-build.R | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/R/plot-build.R b/R/plot-build.R index 5379d9b6b6..dd59fcf4be 100644 --- a/R/plot-build.R +++ b/R/plot-build.R @@ -16,6 +16,8 @@ #' plot). In `get_panel_scales()`, the row of a facet to return scales for. #' @param j An integer. In `get_panel_scales()`, the column of a facet to return #' scales for. +#' @param name A scalar string. In `get_layer_data()` and `get_layer_grob()`, the name of the layer +#' to return. If provided and existing, this takes precedence over `i`. #' @param ... Not currently in use. #' @seealso #' [print.ggplot()] and [benchplot()] for @@ -141,9 +143,16 @@ build_ggplot <- S7::method(ggplot_build, class_ggplot) <- function(plot, ...) { #' @export #' @rdname ggplot_build -get_layer_data <- function(plot = get_last_plot(), i = 1L) { - ggplot_build(plot)@data[[i]] +get_layer_data <- function(plot = get_last_plot(), i = 1L, name = NA) { + if (is.na(name)) { + idx <- i + } else { + name <- arg_match0(name, names(p@layers)) + idx <- which(name == names(p@layers)) + } + ggplot_build(plot)@data[[idx]] } + #' @export #' @rdname ggplot_build layer_data <- get_layer_data @@ -168,10 +177,15 @@ layer_scales <- get_panel_scales #' @export #' @rdname ggplot_build -get_layer_grob <- function(plot = get_last_plot(), i = 1L) { +get_layer_grob <- function(plot = get_last_plot(), i = 1L, name = NA) { b <- ggplot_build(plot) - - b@plot@layers[[i]]$draw_geom(b@data[[i]], b@layout) + if (is.na(name)) { + idx <- i + } else { + idx <- arg_match0(name, names(p@layers)) + idx <- which(name == names(p@layers)) + } + b@plot@layers[[idx]]$draw_geom(b@data[[idx]], b@layout) } #' @export From fa141b8a58e1b9bb8293bedafd99c19429f0d1bd Mon Sep 17 00:00:00 2001 From: Lorenzo Gaborini Date: Mon, 3 Nov 2025 22:09:29 +0100 Subject: [PATCH 2/7] Add layer name tests for get_layer_data(), get_layer_grob() --- tests/testthat/test-layer.R | 95 ++++++++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 16 deletions(-) diff --git a/tests/testthat/test-layer.R b/tests/testthat/test-layer.R index 9528c2927f..17c2c264b0 100644 --- a/tests/testthat/test-layer.R +++ b/tests/testthat/test-layer.R @@ -5,8 +5,18 @@ test_that("layer() checks its input", { expect_snapshot_error(layer(geom = "point", position = "identity")) expect_snapshot_error(layer(geom = "point", stat = "identity")) - expect_snapshot_error(layer("point", "identity", mapping = 1:4, position = "identity")) - expect_snapshot_error(layer("point", "identity", mapping = ggplot(), position = "identity")) + expect_snapshot_error(layer( + "point", + "identity", + mapping = 1:4, + position = "identity" + )) + expect_snapshot_error(layer( + "point", + "identity", + mapping = ggplot(), + position = "identity" + )) expect_snapshot_error(validate_subclass("test", "geom")) expect_snapshot_error(validate_subclass(environment(), "geom")) @@ -29,7 +39,8 @@ test_that("unknown aesthetics create warning", { }) test_that("empty aesthetics create warning", { - p <- ggplot(mtcars) + geom_point(aes(disp, mpg), fill = NULL, shape = character()) + p <- ggplot(mtcars) + + geom_point(aes(disp, mpg), fill = NULL, shape = character()) expect_snapshot_warning(ggplot_build(p)) }) @@ -80,7 +91,13 @@ test_that("function aesthetics are wrapped with after_stat()", { test_that("computed stats are in appropriate layer", { df <- data_frame(x = 1:10) expect_snapshot_error( - ggplot_build(ggplot(df, aes(colour = after_stat(density), fill = after_stat(density))) + geom_point()) + ggplot_build( + ggplot( + df, + aes(colour = after_stat(density), fill = after_stat(density)) + ) + + geom_point() + ) ) }) @@ -96,9 +113,15 @@ test_that("layers are stateless except for the computed params", { p <- ggplot(df) + geom_col(aes(x = x, y = y), width = 0.8, fill = "red") col_layer <- as.list(p@layers[[1]]) - stateless_names <- setdiff(names(col_layer), c("computed_geom_params", "computed_stat_params", "computed_mapping")) + stateless_names <- setdiff( + names(col_layer), + c("computed_geom_params", "computed_stat_params", "computed_mapping") + ) invisible(ggplotGrob(p)) - expect_identical(as.list(p@layers[[1]])[stateless_names], col_layer[stateless_names]) + expect_identical( + as.list(p@layers[[1]])[stateless_names], + col_layer[stateless_names] + ) }) test_that("inherit.aes works", { @@ -109,11 +132,14 @@ test_that("inherit.aes works", { geom_col(aes(x = x, y = y), inherit.aes = FALSE) invisible(ggplotGrob(p1)) invisible(ggplotGrob(p2)) - expect_identical(p1@layers[[1]]$computed_mapping, p2@layers[[1]]$computed_mapping) + expect_identical( + p1@layers[[1]]$computed_mapping, + p2@layers[[1]]$computed_mapping + ) }) test_that("retransform works on computed aesthetics in `map_statistic`", { - df <- data.frame(x = rep(c(1,2), c(9, 25))) + df <- data.frame(x = rep(c(1, 2), c(9, 25))) p <- ggplot(df, aes(x)) + geom_bar() + scale_y_sqrt() expect_equal(get_layer_data(p)$y, c(3, 5)) @@ -147,7 +173,6 @@ test_that("layer warns for constant aesthetics", { }) test_that("layer names can be resolved", { - p <- ggplot() + geom_point() + geom_point() expect_named(p@layers, c("geom_point", "geom_point...2")) @@ -159,7 +184,6 @@ test_that("layer names can be resolved", { }) test_that("validate_subclass can resolve classes via constructors", { - env <- new_environment(list( geom_foobar = geom_point, stat_foobar = stat_boxplot, @@ -169,9 +193,14 @@ test_that("validate_subclass can resolve classes via constructors", { expect_s3_class(validate_subclass("foobar", "Geom", env = env), "GeomPoint") expect_s3_class(validate_subclass("foobar", "Stat", env = env), "StatBoxplot") - expect_s3_class(validate_subclass("foobar", "Position", env = env), "PositionNudge") - expect_s3_class(validate_subclass("foobar", "Guide", env = env), "GuideAxisTheta") - + expect_s3_class( + validate_subclass("foobar", "Position", env = env), + "PositionNudge" + ) + expect_s3_class( + validate_subclass("foobar", "Guide", env = env), + "GuideAxisTheta" + ) }) test_that("attributes on layer data are preserved", { @@ -182,7 +211,9 @@ test_that("attributes on layer data are preserved", { # * It has an `after_stat()` so it enters the map_statistic method old <- stat_summary( aes(fill = after_stat(y)), - fun = mean, geom = "col", position = "dodge" + fun = mean, + geom = "col", + position = "dodge" ) # We modify the compute aesthetics method to append a test attribute new <- ggproto(NULL, old, compute_aesthetics = function(self, data, plot) { @@ -192,7 +223,9 @@ test_that("attributes on layer data are preserved", { }) # At the end of plot building, we want to retrieve that metric ld <- layer_data( - ggplot(mpg, aes(drv, hwy, colour = factor(year))) + new + facet_grid(~year) + + ggplot(mpg, aes(drv, hwy, colour = factor(year))) + + new + + facet_grid(~year) + scale_y_sqrt() ) expect_equal(attr(ld, "test"), "preserve me") @@ -226,6 +259,36 @@ test_that("layer_data returns a data.frame", { expect_snapshot_error(l$layer_data(mtcars)) }) +test_that("get_layer_data works with layer names", { + p <- ggplot() + geom_point(name = "foo") + geom_point(name = "bar") + + # name has higher precedence than index + expect_identical( + get_layer_data(p, i = 1L, name = "bar"), + get_layer_data(p, i = 2L) + ) + + # name falls back to index + expect_snapshot_error( + get_layer_data(p, i = 1L, name = "none") + ) +}) + +test_that("get_layer_grob works with layer names", { + p <- ggplot() + geom_point(name = "foo") + geom_point(name = "bar") + + # name has higher precedence than index + expect_identical( + get_layer_grob(p, i = 1L, name = "bar"), + get_layer_grob(p, i = 2L) + ) + + # name falls back to index + expect_snapshot_error( + get_layer_grob(p, i = 1L, name = "none") + ) +}) + test_that("data.frames and matrix aesthetics survive the build stage", { df <- data_frame0( x = 1:2, @@ -240,5 +303,5 @@ test_that("data.frames and matrix aesthetics survive the build stage", { scale_shape_identity() ) expect_vector(p$colour, matrix(NA_integer_, nrow = 0, ncol = 2), size = 2) - expect_vector(p$shape, data_frame0(a = integer(), b = character()), size = 2) + expect_vector(p$shape, data_frame0(a = integer(), b = character()), size = 2) }) From bae408c47b824e7c55541d14ddf88108509d956d Mon Sep 17 00:00:00 2001 From: Lorenzo Gaborini Date: Mon, 3 Nov 2025 22:21:36 +0100 Subject: [PATCH 3/7] Man --- man/ggplot_build.Rd | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/man/ggplot_build.Rd b/man/ggplot_build.Rd index 1df8de8af1..d58238c936 100644 --- a/man/ggplot_build.Rd +++ b/man/ggplot_build.Rd @@ -12,17 +12,17 @@ \usage{ ggplot_build(plot, ...) -get_layer_data(plot = get_last_plot(), i = 1L) +get_layer_data(plot = get_last_plot(), i = 1L, name = NA) -layer_data(plot = get_last_plot(), i = 1L) +layer_data(plot = get_last_plot(), i = 1L, name = NA) get_panel_scales(plot = get_last_plot(), i = 1L, j = 1L) layer_scales(plot = get_last_plot(), i = 1L, j = 1L) -get_layer_grob(plot = get_last_plot(), i = 1L) +get_layer_grob(plot = get_last_plot(), i = 1L, name = NA) -layer_grob(plot = get_last_plot(), i = 1L) +layer_grob(plot = get_last_plot(), i = 1L, name = NA) } \arguments{ \item{plot}{ggplot object} @@ -33,6 +33,9 @@ layer_grob(plot = get_last_plot(), i = 1L) plot). In \code{get_layer_grob()}, the grob to return (in the order added to the plot). In \code{get_panel_scales()}, the row of a facet to return scales for.} +\item{name}{A scalar string. In \code{get_layer_data()} and \code{get_layer_grob()}, the name of the layer +to return. If provided and existing, this takes precedence over \code{i}.} + \item{j}{An integer. In \code{get_panel_scales()}, the column of a facet to return scales for.} } From cf688a50a543f0ab74033a342b782b262b4ceb9d Mon Sep 17 00:00:00 2001 From: Lorenzo Gaborini Date: Mon, 3 Nov 2025 22:09:29 +0100 Subject: [PATCH 4/7] Fix tests --- man/ggplot_build.Rd | 11 +++++++---- tests/testthat/test-layer.R | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/man/ggplot_build.Rd b/man/ggplot_build.Rd index 1df8de8af1..d58238c936 100644 --- a/man/ggplot_build.Rd +++ b/man/ggplot_build.Rd @@ -12,17 +12,17 @@ \usage{ ggplot_build(plot, ...) -get_layer_data(plot = get_last_plot(), i = 1L) +get_layer_data(plot = get_last_plot(), i = 1L, name = NA) -layer_data(plot = get_last_plot(), i = 1L) +layer_data(plot = get_last_plot(), i = 1L, name = NA) get_panel_scales(plot = get_last_plot(), i = 1L, j = 1L) layer_scales(plot = get_last_plot(), i = 1L, j = 1L) -get_layer_grob(plot = get_last_plot(), i = 1L) +get_layer_grob(plot = get_last_plot(), i = 1L, name = NA) -layer_grob(plot = get_last_plot(), i = 1L) +layer_grob(plot = get_last_plot(), i = 1L, name = NA) } \arguments{ \item{plot}{ggplot object} @@ -33,6 +33,9 @@ layer_grob(plot = get_last_plot(), i = 1L) plot). In \code{get_layer_grob()}, the grob to return (in the order added to the plot). In \code{get_panel_scales()}, the row of a facet to return scales for.} +\item{name}{A scalar string. In \code{get_layer_data()} and \code{get_layer_grob()}, the name of the layer +to return. If provided and existing, this takes precedence over \code{i}.} + \item{j}{An integer. In \code{get_panel_scales()}, the column of a facet to return scales for.} } diff --git a/tests/testthat/test-layer.R b/tests/testthat/test-layer.R index 9528c2927f..32876018df 100644 --- a/tests/testthat/test-layer.R +++ b/tests/testthat/test-layer.R @@ -226,6 +226,36 @@ test_that("layer_data returns a data.frame", { expect_snapshot_error(l$layer_data(mtcars)) }) +test_that("get_layer_data works with layer names", { + p <- ggplot() + geom_point(name = "foo") + geom_point(name = "bar") + + # name has higher precedence than index + expect_identical( + get_layer_data(p, i = 1L, name = "bar"), + get_layer_data(p, i = 2L) + ) + + # name falls back to index + expect_snapshot_error( + get_layer_data(p, i = 1L, name = "none") + ) +}) + +test_that("get_layer_grob works with layer names", { + p <- ggplot() + geom_point(name = "foo") + geom_point(name = "bar") + + # name has higher precedence than index + expect_identical( + get_layer_grob(p, i = 1L, name = "bar"), + get_layer_grob(p, i = 2L) + ) + + # name falls back to index + expect_snapshot_error( + get_layer_grob(p, i = 1L, name = "none") + ) +}) + test_that("data.frames and matrix aesthetics survive the build stage", { df <- data_frame0( x = 1:2, From 8df2e9ad9f5638848fb987cd92958007be2f1bec Mon Sep 17 00:00:00 2001 From: Lorenzo Gaborini Date: Tue, 4 Nov 2025 08:02:51 +0100 Subject: [PATCH 5/7] Fix tests --- tests/testthat/_snaps/layer.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/testthat/_snaps/layer.md b/tests/testthat/_snaps/layer.md index a7ae1d1a85..cc57697394 100644 --- a/tests/testthat/_snaps/layer.md +++ b/tests/testthat/_snaps/layer.md @@ -145,3 +145,11 @@ `layer_data()` must return a . +# get_layer_data works with layer names + + `name` must be one of "foo" or "bar", not "none". + +# get_layer_grob works with layer names + + `name` must be one of "foo" or "bar", not "none". + From bc143c38f23dfef0c6e33b27a3d212fcb9d65e4f Mon Sep 17 00:00:00 2001 From: Lorenzo Gaborini Date: Tue, 4 Nov 2025 08:03:53 +0100 Subject: [PATCH 6/7] Revert formatting changes --- tests/testthat/test-layer.R | 65 +++++++++---------------------------- 1 file changed, 16 insertions(+), 49 deletions(-) diff --git a/tests/testthat/test-layer.R b/tests/testthat/test-layer.R index 17c2c264b0..32876018df 100644 --- a/tests/testthat/test-layer.R +++ b/tests/testthat/test-layer.R @@ -5,18 +5,8 @@ test_that("layer() checks its input", { expect_snapshot_error(layer(geom = "point", position = "identity")) expect_snapshot_error(layer(geom = "point", stat = "identity")) - expect_snapshot_error(layer( - "point", - "identity", - mapping = 1:4, - position = "identity" - )) - expect_snapshot_error(layer( - "point", - "identity", - mapping = ggplot(), - position = "identity" - )) + expect_snapshot_error(layer("point", "identity", mapping = 1:4, position = "identity")) + expect_snapshot_error(layer("point", "identity", mapping = ggplot(), position = "identity")) expect_snapshot_error(validate_subclass("test", "geom")) expect_snapshot_error(validate_subclass(environment(), "geom")) @@ -39,8 +29,7 @@ test_that("unknown aesthetics create warning", { }) test_that("empty aesthetics create warning", { - p <- ggplot(mtcars) + - geom_point(aes(disp, mpg), fill = NULL, shape = character()) + p <- ggplot(mtcars) + geom_point(aes(disp, mpg), fill = NULL, shape = character()) expect_snapshot_warning(ggplot_build(p)) }) @@ -91,13 +80,7 @@ test_that("function aesthetics are wrapped with after_stat()", { test_that("computed stats are in appropriate layer", { df <- data_frame(x = 1:10) expect_snapshot_error( - ggplot_build( - ggplot( - df, - aes(colour = after_stat(density), fill = after_stat(density)) - ) + - geom_point() - ) + ggplot_build(ggplot(df, aes(colour = after_stat(density), fill = after_stat(density))) + geom_point()) ) }) @@ -113,15 +96,9 @@ test_that("layers are stateless except for the computed params", { p <- ggplot(df) + geom_col(aes(x = x, y = y), width = 0.8, fill = "red") col_layer <- as.list(p@layers[[1]]) - stateless_names <- setdiff( - names(col_layer), - c("computed_geom_params", "computed_stat_params", "computed_mapping") - ) + stateless_names <- setdiff(names(col_layer), c("computed_geom_params", "computed_stat_params", "computed_mapping")) invisible(ggplotGrob(p)) - expect_identical( - as.list(p@layers[[1]])[stateless_names], - col_layer[stateless_names] - ) + expect_identical(as.list(p@layers[[1]])[stateless_names], col_layer[stateless_names]) }) test_that("inherit.aes works", { @@ -132,14 +109,11 @@ test_that("inherit.aes works", { geom_col(aes(x = x, y = y), inherit.aes = FALSE) invisible(ggplotGrob(p1)) invisible(ggplotGrob(p2)) - expect_identical( - p1@layers[[1]]$computed_mapping, - p2@layers[[1]]$computed_mapping - ) + expect_identical(p1@layers[[1]]$computed_mapping, p2@layers[[1]]$computed_mapping) }) test_that("retransform works on computed aesthetics in `map_statistic`", { - df <- data.frame(x = rep(c(1, 2), c(9, 25))) + df <- data.frame(x = rep(c(1,2), c(9, 25))) p <- ggplot(df, aes(x)) + geom_bar() + scale_y_sqrt() expect_equal(get_layer_data(p)$y, c(3, 5)) @@ -173,6 +147,7 @@ test_that("layer warns for constant aesthetics", { }) test_that("layer names can be resolved", { + p <- ggplot() + geom_point() + geom_point() expect_named(p@layers, c("geom_point", "geom_point...2")) @@ -184,6 +159,7 @@ test_that("layer names can be resolved", { }) test_that("validate_subclass can resolve classes via constructors", { + env <- new_environment(list( geom_foobar = geom_point, stat_foobar = stat_boxplot, @@ -193,14 +169,9 @@ test_that("validate_subclass can resolve classes via constructors", { expect_s3_class(validate_subclass("foobar", "Geom", env = env), "GeomPoint") expect_s3_class(validate_subclass("foobar", "Stat", env = env), "StatBoxplot") - expect_s3_class( - validate_subclass("foobar", "Position", env = env), - "PositionNudge" - ) - expect_s3_class( - validate_subclass("foobar", "Guide", env = env), - "GuideAxisTheta" - ) + expect_s3_class(validate_subclass("foobar", "Position", env = env), "PositionNudge") + expect_s3_class(validate_subclass("foobar", "Guide", env = env), "GuideAxisTheta") + }) test_that("attributes on layer data are preserved", { @@ -211,9 +182,7 @@ test_that("attributes on layer data are preserved", { # * It has an `after_stat()` so it enters the map_statistic method old <- stat_summary( aes(fill = after_stat(y)), - fun = mean, - geom = "col", - position = "dodge" + fun = mean, geom = "col", position = "dodge" ) # We modify the compute aesthetics method to append a test attribute new <- ggproto(NULL, old, compute_aesthetics = function(self, data, plot) { @@ -223,9 +192,7 @@ test_that("attributes on layer data are preserved", { }) # At the end of plot building, we want to retrieve that metric ld <- layer_data( - ggplot(mpg, aes(drv, hwy, colour = factor(year))) + - new + - facet_grid(~year) + + ggplot(mpg, aes(drv, hwy, colour = factor(year))) + new + facet_grid(~year) + scale_y_sqrt() ) expect_equal(attr(ld, "test"), "preserve me") @@ -303,5 +270,5 @@ test_that("data.frames and matrix aesthetics survive the build stage", { scale_shape_identity() ) expect_vector(p$colour, matrix(NA_integer_, nrow = 0, ncol = 2), size = 2) - expect_vector(p$shape, data_frame0(a = integer(), b = character()), size = 2) + expect_vector(p$shape, data_frame0(a = integer(), b = character()), size = 2) }) From 5a877c35f7d0d3a20e478119ef94cf8f33569e4a Mon Sep 17 00:00:00 2001 From: Lorenzo Gaborini Date: Tue, 4 Nov 2025 10:42:25 +0100 Subject: [PATCH 7/7] get_layer_data(), get_layer_grob() now accept integers or characters --- R/plot-build.R | 36 ++++++++++++++++------------------ man/ggplot_build.Rd | 15 ++++++-------- tests/testthat/_snaps/layer.md | 18 +++++++++++++++-- tests/testthat/test-layer.R | 14 +++++++++---- 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/R/plot-build.R b/R/plot-build.R index dd59fcf4be..a1b867b911 100644 --- a/R/plot-build.R +++ b/R/plot-build.R @@ -11,13 +11,11 @@ #' layer. These are useful for tests. #' #' @param plot ggplot object -#' @param i An integer. In `get_layer_data()`, the data to return (in the order added to the +#' @param i An integer or a name of a layer. In `get_layer_data()`, the data to return (in the order added to the #' plot). In `get_layer_grob()`, the grob to return (in the order added to the -#' plot). In `get_panel_scales()`, the row of a facet to return scales for. +#' plot). In `get_panel_scales()` (only integers allowed), the row of a facet to return scales for. #' @param j An integer. In `get_panel_scales()`, the column of a facet to return #' scales for. -#' @param name A scalar string. In `get_layer_data()` and `get_layer_grob()`, the name of the layer -#' to return. If provided and existing, this takes precedence over `i`. #' @param ... Not currently in use. #' @seealso #' [print.ggplot()] and [benchplot()] for @@ -143,14 +141,14 @@ build_ggplot <- S7::method(ggplot_build, class_ggplot) <- function(plot, ...) { #' @export #' @rdname ggplot_build -get_layer_data <- function(plot = get_last_plot(), i = 1L, name = NA) { - if (is.na(name)) { - idx <- i - } else { - name <- arg_match0(name, names(p@layers)) - idx <- which(name == names(p@layers)) - } - ggplot_build(plot)@data[[idx]] +get_layer_data <- function(plot = get_last_plot(), i = 1L) { + b <- ggplot_build(plot) + idx <- vec_as_location2( + i = i, + n = vec_size(b@plot@layers), + names = names(b@plot@layers) + ) + b@data[[idx]] } #' @export @@ -177,14 +175,14 @@ layer_scales <- get_panel_scales #' @export #' @rdname ggplot_build -get_layer_grob <- function(plot = get_last_plot(), i = 1L, name = NA) { +get_layer_grob <- function(plot = get_last_plot(), i = 1L) { b <- ggplot_build(plot) - if (is.na(name)) { - idx <- i - } else { - idx <- arg_match0(name, names(p@layers)) - idx <- which(name == names(p@layers)) - } + + idx <- vec_as_location2( + i = i, + n = vec_size(b@plot@layers), + names = names(b@plot@layers) + ) b@plot@layers[[idx]]$draw_geom(b@data[[idx]], b@layout) } diff --git a/man/ggplot_build.Rd b/man/ggplot_build.Rd index d58238c936..5579c8a659 100644 --- a/man/ggplot_build.Rd +++ b/man/ggplot_build.Rd @@ -12,29 +12,26 @@ \usage{ ggplot_build(plot, ...) -get_layer_data(plot = get_last_plot(), i = 1L, name = NA) +get_layer_data(plot = get_last_plot(), i = 1L) -layer_data(plot = get_last_plot(), i = 1L, name = NA) +layer_data(plot = get_last_plot(), i = 1L) get_panel_scales(plot = get_last_plot(), i = 1L, j = 1L) layer_scales(plot = get_last_plot(), i = 1L, j = 1L) -get_layer_grob(plot = get_last_plot(), i = 1L, name = NA) +get_layer_grob(plot = get_last_plot(), i = 1L) -layer_grob(plot = get_last_plot(), i = 1L, name = NA) +layer_grob(plot = get_last_plot(), i = 1L) } \arguments{ \item{plot}{ggplot object} \item{...}{Not currently in use.} -\item{i}{An integer. In \code{get_layer_data()}, the data to return (in the order added to the +\item{i}{An integer or a name of a layer. In \code{get_layer_data()}, the data to return (in the order added to the plot). In \code{get_layer_grob()}, the grob to return (in the order added to the -plot). In \code{get_panel_scales()}, the row of a facet to return scales for.} - -\item{name}{A scalar string. In \code{get_layer_data()} and \code{get_layer_grob()}, the name of the layer -to return. If provided and existing, this takes precedence over \code{i}.} +plot). In \code{get_panel_scales()} (only integers allowed), the row of a facet to return scales for.} \item{j}{An integer. In \code{get_panel_scales()}, the column of a facet to return scales for.} diff --git a/tests/testthat/_snaps/layer.md b/tests/testthat/_snaps/layer.md index cc57697394..724788f430 100644 --- a/tests/testthat/_snaps/layer.md +++ b/tests/testthat/_snaps/layer.md @@ -147,9 +147,23 @@ # get_layer_data works with layer names - `name` must be one of "foo" or "bar", not "none". + Can't extract elements that don't exist. + x Element `none` doesn't exist. + +--- + + Can't extract elements past the end. + i Location 4 doesn't exist. + i There are only 2 elements. # get_layer_grob works with layer names - `name` must be one of "foo" or "bar", not "none". + Can't extract elements that don't exist. + x Element `none` doesn't exist. + +--- + + Can't extract elements past the end. + i Location 4 doesn't exist. + i There are only 2 elements. diff --git a/tests/testthat/test-layer.R b/tests/testthat/test-layer.R index 32876018df..a7407db05c 100644 --- a/tests/testthat/test-layer.R +++ b/tests/testthat/test-layer.R @@ -231,13 +231,16 @@ test_that("get_layer_data works with layer names", { # name has higher precedence than index expect_identical( - get_layer_data(p, i = 1L, name = "bar"), + get_layer_data(p, i = "bar"), get_layer_data(p, i = 2L) ) # name falls back to index expect_snapshot_error( - get_layer_data(p, i = 1L, name = "none") + get_layer_data(p, i ="none") + ) + expect_snapshot_error( + get_layer_data(p, i = 4L) ) }) @@ -246,13 +249,16 @@ test_that("get_layer_grob works with layer names", { # name has higher precedence than index expect_identical( - get_layer_grob(p, i = 1L, name = "bar"), + get_layer_grob(p, i = "bar"), get_layer_grob(p, i = 2L) ) # name falls back to index expect_snapshot_error( - get_layer_grob(p, i = 1L, name = "none") + get_layer_grob(p, i ="none") + ) + expect_snapshot_error( + get_layer_grob(p, i = 4L) ) })