diff --git a/R/plot-build.R b/R/plot-build.R index 5379d9b6b6..a1b867b911 100644 --- a/R/plot-build.R +++ b/R/plot-build.R @@ -11,9 +11,9 @@ #' 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 ... Not currently in use. @@ -142,8 +142,15 @@ 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]] + 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 #' @rdname ggplot_build layer_data <- get_layer_data @@ -171,7 +178,12 @@ layer_scales <- get_panel_scales get_layer_grob <- function(plot = get_last_plot(), i = 1L) { b <- ggplot_build(plot) - b@plot@layers[[i]]$draw_geom(b@data[[i]], b@layout) + 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) } #' @export diff --git a/man/ggplot_build.Rd b/man/ggplot_build.Rd index 1df8de8af1..5579c8a659 100644 --- a/man/ggplot_build.Rd +++ b/man/ggplot_build.Rd @@ -29,9 +29,9 @@ layer_grob(plot = get_last_plot(), i = 1L) \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.} +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 a7ae1d1a85..724788f430 100644 --- a/tests/testthat/_snaps/layer.md +++ b/tests/testthat/_snaps/layer.md @@ -145,3 +145,25 @@ `layer_data()` must return a . +# get_layer_data works with layer names + + 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 + + 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 9528c2927f..a7407db05c 100644 --- a/tests/testthat/test-layer.R +++ b/tests/testthat/test-layer.R @@ -226,6 +226,42 @@ 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 = "bar"), + get_layer_data(p, i = 2L) + ) + + # name falls back to index + expect_snapshot_error( + get_layer_data(p, i ="none") + ) + expect_snapshot_error( + get_layer_data(p, i = 4L) + ) +}) + +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 = "bar"), + get_layer_grob(p, i = 2L) + ) + + # name falls back to index + expect_snapshot_error( + get_layer_grob(p, i ="none") + ) + expect_snapshot_error( + get_layer_grob(p, i = 4L) + ) +}) + test_that("data.frames and matrix aesthetics survive the build stage", { df <- data_frame0( x = 1:2,