From 7321e4705ac83f7e86f6a86991ebe1fe2ae164ed Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 23 May 2022 10:13:02 +0200 Subject: [PATCH 1/8] Update ggproto to call methods by name instead of through f() --- R/ggproto.r | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/R/ggproto.r b/R/ggproto.r index 04cd0a0198..4607ae03d9 100644 --- a/R/ggproto.r +++ b/R/ggproto.r @@ -153,7 +153,7 @@ fetch_ggproto <- function(x, name) { return(res) } - make_proto_method(x, res) + make_proto_method(x, res, name) } #' @export @@ -163,19 +163,22 @@ fetch_ggproto <- function(x, name) { return(res) } - make_proto_method(.subset2(x, "self"), res) + make_proto_method(.subset2(x, "self"), res, name) } -make_proto_method <- function(self, f) { +make_proto_method <- function(self, f, name) { args <- formals(f) # is.null is a fast path for a common case; the %in% check is slower but also # catches the case where there's a `self = NULL` argument. has_self <- !is.null(args[["self"]]) || "self" %in% names(args) + # We assign the method with its correct name and construct a call to it to + # make errors reported as coming from the method name rather than `f()` + assign(name, f, envir = environment()) if (has_self) { - fun <- function(...) f(..., self = self) + fun <- inject(function(...) !!call2(name, quote(...), self = quote(self))) } else { - fun <- function(...) f(...) + fun <- inject(function(...) !!call2(name, quote(...))) } class(fun) <- "ggproto_method" From 8e3ff5a124bc8a7713ead3f7aeead7ab6ce2491f Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 23 May 2022 10:13:28 +0200 Subject: [PATCH 2/8] Fix error wording --- R/layer.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/layer.r b/R/layer.r index 5cdf9d241c..f4db11d6fe 100644 --- a/R/layer.r +++ b/R/layer.r @@ -328,7 +328,7 @@ Layer <- ggproto("Layer", NULL, issues <- paste0("{.code ", nondata_stat_cols, " = ", as_label(aesthetics[[nondata_stat_cols]]), "}") names(issues) <- rep("x", length(issues)) cli::cli_abort(c( - "Aesthetics are not valid computed stats.", + "Aesthetics must be valid computed stats.", "x" = "The following aesthetics are invalid:", issues, "i" = "Did you map your stat in the wrong layer?" From bad27209c4b07b3e8fe2a6274b890a7f17b00267 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 23 May 2022 10:16:21 +0200 Subject: [PATCH 3/8] Store the layer constructor in the layer --- R/layer-sf.R | 6 +++++- R/layer.r | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/R/layer-sf.R b/R/layer-sf.R index c583fba16d..3fcf8fd2cd 100644 --- a/R/layer-sf.R +++ b/R/layer-sf.R @@ -13,6 +13,7 @@ layer_sf <- function(geom = NULL, stat = NULL, position = NULL, params = list(), inherit.aes = TRUE, check.aes = TRUE, check.param = TRUE, show.legend = NA) { + call_env <- caller_env() if (is.character(show.legend)) { legend_key_type <- show.legend show.legend <- TRUE @@ -21,7 +22,10 @@ layer_sf <- function(geom = NULL, stat = NULL, } # inherit from LayerSf class to add `legend_key_type` slot - layer_class <- ggproto(NULL, LayerSf, legend_key_type = legend_key_type) + layer_class <- ggproto(NULL, LayerSf, + constructor = frame_call(call_env), + legend_key_type = legend_key_type + ) layer( geom = geom, stat = stat, data = data, mapping = mapping, diff --git a/R/layer.r b/R/layer.r index f4db11d6fe..b065a2c10d 100644 --- a/R/layer.r +++ b/R/layer.r @@ -140,7 +140,10 @@ layer <- function(geom = NULL, stat = NULL, # adjust the legend draw key if requested geom <- set_draw_key(geom, key_glyph) + fr_call <- layer_class$constructor %||% frame_call(call_env) + ggproto("LayerInstance", layer_class, + constructor = fr_call, geom = geom, geom_params = geom_params, stat = stat, @@ -169,6 +172,7 @@ validate_mapping <- function(mapping, call = caller_env()) { } Layer <- ggproto("Layer", NULL, + constructor = NULL, geom = NULL, geom_params = NULL, stat = NULL, From 887ec8d9e851c551dd663525784d400871b4eef8 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 23 May 2022 10:17:13 +0200 Subject: [PATCH 4/8] modify by_layer to use try_fetch and throw contextual errors --- R/plot-build.r | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/R/plot-build.r b/R/plot-build.r index e1c8b8acc6..ca2920331c 100644 --- a/R/plot-build.r +++ b/R/plot-build.r @@ -35,19 +35,11 @@ ggplot_build.ggplot <- function(plot) { data <- rep(list(NULL), length(layers)) scales <- plot$scales - # Apply function to layer and matching data - by_layer <- function(f) { - out <- vector("list", length(data)) - for (i in seq_along(data)) { - out[[i]] <- f(l = layers[[i]], d = data[[i]]) - } - out - } # Allow all layers to make any final adjustments based # on raw input data and plot info - data <- by_layer(function(l, d) l$layer_data(plot$data)) - data <- by_layer(function(l, d) l$setup_layer(d, plot)) + data <- by_layer(function(l, d) l$layer_data(plot$data), layers, data, "computing layer data") + data <- by_layer(function(l, d) l$setup_layer(d, plot), layers, data, "setting up layer") # Initialise panels, add extra data for margins & missing faceting # variables, and add on a PANEL variable to data @@ -55,7 +47,7 @@ ggplot_build.ggplot <- function(plot) { data <- layout$setup(data, plot$data, plot$plot_env) # Compute aesthetics to produce data with generalised variable names - data <- by_layer(function(l, d) l$compute_aesthetics(d, plot)) + data <- by_layer(function(l, d) l$compute_aesthetics(d, plot), layers, data, "computing aesthetics") # Transform all scales data <- lapply(data, scales_transform_df, scales = scales) @@ -69,17 +61,17 @@ ggplot_build.ggplot <- function(plot) { data <- layout$map_position(data) # Apply and map statistics - data <- by_layer(function(l, d) l$compute_statistic(d, layout)) - data <- by_layer(function(l, d) l$map_statistic(d, plot)) + data <- by_layer(function(l, d) l$compute_statistic(d, layout), layers, data, "computing statistics") + data <- by_layer(function(l, d) l$map_statistic(d, plot), layers, data, "mapping statistics to aesthetics") # Make sure missing (but required) aesthetics are added scales_add_missing(plot, c("x", "y"), plot$plot_env) # Reparameterise geoms from (e.g.) y and width to ymin and ymax - data <- by_layer(function(l, d) l$compute_geom_1(d)) + data <- by_layer(function(l, d) l$compute_geom_1(d), layers, data, "setting up geom") # Apply position adjustments - data <- by_layer(function(l, d) l$compute_position(d, layout)) + data <- by_layer(function(l, d) l$compute_position(d, layout), layers, data, "computing positions") # Reset position scales, then re-train and map. This ensures that facets # have control over the range of a plot: is it generated from what is @@ -97,10 +89,10 @@ ggplot_build.ggplot <- function(plot) { } # Fill in defaults etc. - data <- by_layer(function(l, d) l$compute_geom_2(d)) + data <- by_layer(function(l, d) l$compute_geom_2(d), layers, data, "setting up geom aesthetics") # Let layer stat have a final say before rendering - data <- by_layer(function(l, d) l$finish_statistics(d)) + data <- by_layer(function(l, d) l$finish_statistics(d), layers, data, "finishing layer stat") # Let Layout modify data before rendering data <- layout$finish_data(data) @@ -168,7 +160,7 @@ ggplot_gtable.ggplot_built <- function(data) { data <- data$data theme <- plot_theme(plot) - geom_grobs <- Map(function(l, d) l$draw_geom(d, layout), plot$layers, data) + geom_grobs <- by_layer(function(l, d) l$draw_geom(d, layout), plot$layers, data, "converting geom to grob") layout$setup_panel_guides(plot$guides, plot$layers, plot$mapping) plot_table <- layout$render(geom_grobs, data, theme, plot$labels) @@ -419,3 +411,18 @@ ggplot_gtable.ggplot_built <- function(data) { ggplotGrob <- function(x) { ggplot_gtable(ggplot_build(x)) } + +# Apply function to layer and matching data +by_layer <- function(f, layers, data, step = NULL) { + ordinal <- label_ordinal() + out <- vector("list", length(data)) + try_fetch( + for (i in seq_along(data)) { + out[[i]] <- f(l = layers[[i]], d = data[[i]]) + }, + error = function(cnd) { + cli::cli_abort(c("Problem {step}", "i" = "Error occurred in the {ordinal(i)} layer"), call = I(layers[[i]]$constructor), parent = cnd) + } + ) + out +} From ee392abed288e0a89f11803dab5b037488cfc2d9 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 23 May 2022 10:17:27 +0200 Subject: [PATCH 5/8] update test snapshots --- tests/testthat/_snaps/annotate.md | 10 ++++++++-- tests/testthat/_snaps/geom-.md | 5 ++++- tests/testthat/_snaps/geom-dotplot.md | 4 ++-- tests/testthat/_snaps/geom-linerange.md | 5 ++++- tests/testthat/_snaps/geom-path.md | 5 ++++- tests/testthat/_snaps/geom-raster.md | 5 ++++- tests/testthat/_snaps/geom-ribbon.md | 15 +++++++++++--- tests/testthat/_snaps/geom-sf.md | 5 ++++- tests/testthat/_snaps/geom-violin.md | 10 ++++++++-- tests/testthat/_snaps/guides.md | 20 +++++++++---------- tests/testthat/_snaps/layer.md | 20 +++++++++++++++---- tests/testthat/_snaps/position-jitterdodge.md | 5 ++++- tests/testthat/_snaps/stat-bin.md | 20 +++++++++++++++---- tests/testthat/_snaps/stat-boxplot.md | 5 ++++- tests/testthat/_snaps/stat-count.md | 10 ++++++++-- tests/testthat/_snaps/stat-density.md | 5 ++++- tests/testthat/_snaps/stat-density2d.md | 5 ++++- tests/testthat/_snaps/stat-ecdf.md | 5 ++++- tests/testthat/_snaps/stat-qq.md | 6 +++--- 19 files changed, 123 insertions(+), 42 deletions(-) diff --git a/tests/testthat/_snaps/annotate.md b/tests/testthat/_snaps/annotate.md index 02c670d6a6..49bdbae686 100644 --- a/tests/testthat/_snaps/annotate.md +++ b/tests/testthat/_snaps/annotate.md @@ -1,10 +1,16 @@ # annotation_raster() and annotation_custom() requires cartesian coordinates - `annotation_raster()` only works with `coord_cartesian()` + Problem converting geom to grob + i Error occurred in the 1st layer + Caused by error in `draw_panel()`: + ! `annotation_raster()` only works with `coord_cartesian()` --- - `annotation_custom()` only works with `coord_cartesian()` + Problem converting geom to grob + i Error occurred in the 1st layer + Caused by error in `draw_panel()`: + ! `annotation_custom()` only works with `coord_cartesian()` # annotation_map() checks the input data diff --git a/tests/testthat/_snaps/geom-.md b/tests/testthat/_snaps/geom-.md index 08c938f136..5b1a09893b 100644 --- a/tests/testthat/_snaps/geom-.md +++ b/tests/testthat/_snaps/geom-.md @@ -1,6 +1,9 @@ # aesthetic checking in geom throws correct errors - Aesthetic modifiers returned invalid values + Problem setting up geom aesthetics + i Error occurred in the 1st layer + Caused by error in `use_defaults()`: + ! Aesthetic modifiers returned invalid values x The following mappings are invalid x `colour = after_scale(data)` i Did you map the modifier in the wrong layer? diff --git a/tests/testthat/_snaps/geom-dotplot.md b/tests/testthat/_snaps/geom-dotplot.md index 020e4dc948..b2e9f5b5ac 100644 --- a/tests/testthat/_snaps/geom-dotplot.md +++ b/tests/testthat/_snaps/geom-dotplot.md @@ -5,12 +5,12 @@ # weight aesthetic is checked Computation failed in `stat_bindot()` - Caused by error in `f()`: + Caused by error in `compute_group()`: ! Weights must be nonnegative integers. --- Computation failed in `stat_bindot()` - Caused by error in `f()`: + Caused by error in `compute_group()`: ! Weights must be nonnegative integers. diff --git a/tests/testthat/_snaps/geom-linerange.md b/tests/testthat/_snaps/geom-linerange.md index 0ed2d2f407..c4aba72fee 100644 --- a/tests/testthat/_snaps/geom-linerange.md +++ b/tests/testthat/_snaps/geom-linerange.md @@ -1,4 +1,7 @@ # geom_linerange request the right aesthetics - `geom_linerange()` requires the following missing aesthetics: ymax or xmin and xmax + Problem setting up geom + i Error occurred in the 1st layer + Caused by error in `compute_geom_1()`: + ! `geom_linerange()` requires the following missing aesthetics: ymax or xmin and xmax diff --git a/tests/testthat/_snaps/geom-path.md b/tests/testthat/_snaps/geom-path.md index c649779131..8faf36169e 100644 --- a/tests/testthat/_snaps/geom-path.md +++ b/tests/testthat/_snaps/geom-path.md @@ -1,4 +1,7 @@ # geom_path() throws meaningful error on bad combination of varying aesthetics - `geom_path()` can't have varying colour, size, and/or alpha along the line when linetype isn't solid + Problem converting geom to grob + i Error occurred in the 1st layer + Caused by error in `draw_panel()`: + ! `geom_path()` can't have varying colour, size, and/or alpha along the line when linetype isn't solid diff --git a/tests/testthat/_snaps/geom-raster.md b/tests/testthat/_snaps/geom-raster.md index 342f4a3c4c..472621c042 100644 --- a/tests/testthat/_snaps/geom-raster.md +++ b/tests/testthat/_snaps/geom-raster.md @@ -16,5 +16,8 @@ --- - `geom_raster()` only works with `coord_cartesian()` + Problem converting geom to grob + i Error occurred in the 1st layer + Caused by error in `draw_panel()`: + ! `geom_raster()` only works with `coord_cartesian()` diff --git a/tests/testthat/_snaps/geom-ribbon.md b/tests/testthat/_snaps/geom-ribbon.md index a76f72a577..0521405dae 100644 --- a/tests/testthat/_snaps/geom-ribbon.md +++ b/tests/testthat/_snaps/geom-ribbon.md @@ -1,14 +1,23 @@ # geom_ribbon() checks the aesthetics - Either xmin or xmax must be given as an aesthetic. + Problem setting up geom + i Error occurred in the 1st layer + Caused by error in `setup_data()`: + ! Either xmin or xmax must be given as an aesthetic. --- - Either ymin or ymax must be given as an aesthetic. + Problem setting up geom + i Error occurred in the 1st layer + Caused by error in `setup_data()`: + ! Either ymin or ymax must be given as an aesthetic. --- - Aesthetics can not vary along a ribbon + Problem converting geom to grob + i Error occurred in the 1st layer + Caused by error in `draw_group()`: + ! Aesthetics can not vary along a ribbon --- diff --git a/tests/testthat/_snaps/geom-sf.md b/tests/testthat/_snaps/geom-sf.md index 180b0b277b..b9c09fda3d 100644 --- a/tests/testthat/_snaps/geom-sf.md +++ b/tests/testthat/_snaps/geom-sf.md @@ -1,6 +1,9 @@ # errors are correctly triggered - `geom_sf()` can only be used with `coord_sf()` + Problem converting geom to grob + i Error occurred in the 1st layer + Caused by error in `draw_panel()`: + ! `geom_sf()` can only be used with `coord_sf()` --- diff --git a/tests/testthat/_snaps/geom-violin.md b/tests/testthat/_snaps/geom-violin.md index acf43a4654..e3608a86c2 100644 --- a/tests/testthat/_snaps/geom-violin.md +++ b/tests/testthat/_snaps/geom-violin.md @@ -1,8 +1,14 @@ # quantiles fails outside 0-1 bound - `draw_quantiles` must be between 0 and 1 + Problem converting geom to grob + i Error occurred in the 1st layer + Caused by error in `draw_group()`: + ! `draw_quantiles` must be between 0 and 1 --- - `draw_quantiles` must be between 0 and 1 + Problem converting geom to grob + i Error occurred in the 1st layer + Caused by error in `draw_group()`: + ! `draw_quantiles` must be between 0 and 1 diff --git a/tests/testthat/_snaps/guides.md b/tests/testthat/_snaps/guides.md index 4b9f4b317b..88a8a97b71 100644 --- a/tests/testthat/_snaps/guides.md +++ b/tests/testthat/_snaps/guides.md @@ -1,13 +1,3 @@ -# binning scales understand the different combinations of limits, breaks, labels, and show.limits - - `show.limits` is ignored when `labels` are given as a character vector - i Either add the limits to `breaks` or provide a function for `labels` - ---- - - `show.limits` is ignored when `labels` are given as a character vector - i Either add the limits to `breaks` or provide a function for `labels` - # axis_label_element_overrides errors when angles are outside the range [0, 90] Unrecognized `axis_position`: "test" @@ -68,6 +58,16 @@ Breaks not formatted correctly for a bin legend. i Use `(, ]` format to indicate bins +# binning scales understand the different combinations of limits, breaks, labels, and show.limits + + `show.limits` is ignored when `labels` are given as a character vector + i Either add the limits to `breaks` or provide a function for `labels` + +--- + + `show.limits` is ignored when `labels` are given as a character vector + i Either add the limits to `breaks` or provide a function for `labels` + # a warning is generated when guides( = FALSE) is specified `guide = FALSE` is deprecated diff --git a/tests/testthat/_snaps/layer.md b/tests/testthat/_snaps/layer.md index 76b269cf88..a3c62a08dd 100644 --- a/tests/testthat/_snaps/layer.md +++ b/tests/testthat/_snaps/layer.md @@ -29,21 +29,30 @@ # invalid aesthetics throws errors - Aesthetics are not valid data columns. + Problem computing aesthetics + i Error occurred in the 1st layer + Caused by error in `compute_aesthetics()`: + ! Aesthetics are not valid data columns. x The following aesthetics are invalid: x `fill = data` i Did you mistype the name of a data column or forget to add `after_stat()`? --- - Aesthetics are not valid computed stats. + Problem mapping statistics to aesthetics + i Error occurred in the 1st layer + Caused by error in `map_statistic()`: + ! Aesthetics must be valid computed stats. x The following aesthetics are invalid: x `fill = after_stat(data)` i Did you map your stat in the wrong layer? # function aesthetics are wrapped with stat() - Aesthetics are not valid data columns. + Problem computing aesthetics + i Error occurred in the 1st layer + Caused by error in `compute_aesthetics()`: + ! Aesthetics are not valid data columns. x The following aesthetics are invalid: x `colour = NULL` x `fill = NULL` @@ -51,7 +60,10 @@ # computed stats are in appropriate layer - Aesthetics are not valid computed stats. + Problem mapping statistics to aesthetics + i Error occurred in the 1st layer + Caused by error in `map_statistic()`: + ! Aesthetics must be valid computed stats. x The following aesthetics are invalid: x `colour = NULL` x `fill = NULL` diff --git a/tests/testthat/_snaps/position-jitterdodge.md b/tests/testthat/_snaps/position-jitterdodge.md index ca5337eedc..485d8bbf02 100644 --- a/tests/testthat/_snaps/position-jitterdodge.md +++ b/tests/testthat/_snaps/position-jitterdodge.md @@ -1,4 +1,7 @@ # position_jitterdodge() fails with meaningful error - `position_jitterdodge()` requires at least one aesthetic to dodge by + Problem computing positions + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `position_jitterdodge()` requires at least one aesthetic to dodge by diff --git a/tests/testthat/_snaps/stat-bin.md b/tests/testthat/_snaps/stat-bin.md index 9bcf6dad64..aabdc610f2 100644 --- a/tests/testthat/_snaps/stat-bin.md +++ b/tests/testthat/_snaps/stat-bin.md @@ -1,14 +1,23 @@ # stat_bin throws error when wrong combination of aesthetic is present - `stat_bin()` requires an x or y aesthetic. + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `stat_bin()` requires an x or y aesthetic. --- - `stat_bin()` must only have an x or y aesthetic. + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `stat_bin()` must only have an x or y aesthetic. --- - `stat_bin()` requires a continuous x aesthetic + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `stat_bin()` requires a continuous x aesthetic x the x aesthetic is discrete. i Perhaps you want `stat="count"`? @@ -46,5 +55,8 @@ # stat_count throws error when both x and y aesthetic present - `stat_count()` must only have an x or y aesthetic. + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `stat_count()` must only have an x or y aesthetic. diff --git a/tests/testthat/_snaps/stat-boxplot.md b/tests/testthat/_snaps/stat-boxplot.md index 1f95358b33..2e930ca60b 100644 --- a/tests/testthat/_snaps/stat-boxplot.md +++ b/tests/testthat/_snaps/stat-boxplot.md @@ -8,5 +8,8 @@ # stat_boxplot errors with missing x/y aesthetics - `stat_boxplot()` requires an x or y aesthetic. + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `stat_boxplot()` requires an x or y aesthetic. diff --git a/tests/testthat/_snaps/stat-count.md b/tests/testthat/_snaps/stat-count.md index 2229ecc762..fb62f3233b 100644 --- a/tests/testthat/_snaps/stat-count.md +++ b/tests/testthat/_snaps/stat-count.md @@ -1,8 +1,14 @@ # stat_count() checks the aesthetics - `stat_count()` requires an x or y aesthetic. + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `stat_count()` requires an x or y aesthetic. --- - `stat_count()` must only have an x or y aesthetic. + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `stat_count()` must only have an x or y aesthetic. diff --git a/tests/testthat/_snaps/stat-density.md b/tests/testthat/_snaps/stat-density.md index 31e70ca675..66dce9699a 100644 --- a/tests/testthat/_snaps/stat-density.md +++ b/tests/testthat/_snaps/stat-density.md @@ -1,4 +1,7 @@ # stat_density works in both directions - `stat_density()` requires an x or y aesthetic. + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `stat_density()` requires an x or y aesthetic. diff --git a/tests/testthat/_snaps/stat-density2d.md b/tests/testthat/_snaps/stat-density2d.md index 54a9c30575..0aafb0754b 100644 --- a/tests/testthat/_snaps/stat-density2d.md +++ b/tests/testthat/_snaps/stat-density2d.md @@ -1,5 +1,8 @@ # stat_density2d can produce contour and raster data - Invalid value of `contour_var` ("abcd") + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `compute_layer()`: + ! Invalid value of `contour_var` ("abcd") i Supported values are "density", "ndensity", and "count". diff --git a/tests/testthat/_snaps/stat-ecdf.md b/tests/testthat/_snaps/stat-ecdf.md index ef492fab44..74b2187ce3 100644 --- a/tests/testthat/_snaps/stat-ecdf.md +++ b/tests/testthat/_snaps/stat-ecdf.md @@ -1,4 +1,7 @@ # stat_ecdf works in both directions - `stat_ecdf()` requires an x or y aesthetic. + Problem computing statistics + i Error occurred in the 1st layer + Caused by error in `setup_params()`: + ! `stat_ecdf()` requires an x or y aesthetic. diff --git a/tests/testthat/_snaps/stat-qq.md b/tests/testthat/_snaps/stat-qq.md index 0c22addb7c..24f4890db7 100644 --- a/tests/testthat/_snaps/stat-qq.md +++ b/tests/testthat/_snaps/stat-qq.md @@ -1,18 +1,18 @@ # error is thrown with wrong quantile input Computation failed in `stat_qq()` - Caused by error in `f()`: + Caused by error in `compute_group()`: ! The length of `quantiles` must match the length of the data --- Computation failed in `stat_qq_line()` - Caused by error in `f()`: + Caused by error in `compute_group()`: ! `quantiles` must have the same length as the data --- Computation failed in `stat_qq_line()` - Caused by error in `f()`: + Caused by error in `compute_group()`: ! Cannot fit line quantiles 0.15. `line.p` must have length 2. From 50d999f38caa58d0d0a62339c4b97a2d6714eeea Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 23 May 2022 10:34:07 +0200 Subject: [PATCH 6/8] improve method construction in ggproto --- R/ggproto.r | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/ggproto.r b/R/ggproto.r index 4607ae03d9..d6b0533f01 100644 --- a/R/ggproto.r +++ b/R/ggproto.r @@ -175,11 +175,11 @@ make_proto_method <- function(self, f, name) { # We assign the method with its correct name and construct a call to it to # make errors reported as coming from the method name rather than `f()` assign(name, f, envir = environment()) + args <- list(quote(...)) if (has_self) { - fun <- inject(function(...) !!call2(name, quote(...), self = quote(self))) - } else { - fun <- inject(function(...) !!call2(name, quote(...))) + args$self <- quote(self) } + fun <- inject(function(...) !!call2(name, !!!args)) class(fun) <- "ggproto_method" fun From 9c3eb9cdb5129709ca8140e63f39a3f2732664fc Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Tue, 24 May 2022 14:08:35 +0200 Subject: [PATCH 7/8] imrpove message based on comments --- R/plot-build.r | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/plot-build.r b/R/plot-build.r index ca2920331c..c5fc0a566c 100644 --- a/R/plot-build.r +++ b/R/plot-build.r @@ -61,8 +61,8 @@ ggplot_build.ggplot <- function(plot) { data <- layout$map_position(data) # Apply and map statistics - data <- by_layer(function(l, d) l$compute_statistic(d, layout), layers, data, "computing statistics") - data <- by_layer(function(l, d) l$map_statistic(d, plot), layers, data, "mapping statistics to aesthetics") + data <- by_layer(function(l, d) l$compute_statistic(d, layout), layers, data, "computing stat") + data <- by_layer(function(l, d) l$map_statistic(d, plot), layers, data, "mapping stat to aesthetics") # Make sure missing (but required) aesthetics are added scales_add_missing(plot, c("x", "y"), plot$plot_env) @@ -71,7 +71,7 @@ ggplot_build.ggplot <- function(plot) { data <- by_layer(function(l, d) l$compute_geom_1(d), layers, data, "setting up geom") # Apply position adjustments - data <- by_layer(function(l, d) l$compute_position(d, layout), layers, data, "computing positions") + data <- by_layer(function(l, d) l$compute_position(d, layout), layers, data, "computing position") # Reset position scales, then re-train and map. This ensures that facets # have control over the range of a plot: is it generated from what is @@ -421,7 +421,7 @@ by_layer <- function(f, layers, data, step = NULL) { out[[i]] <- f(l = layers[[i]], d = data[[i]]) }, error = function(cnd) { - cli::cli_abort(c("Problem {step}", "i" = "Error occurred in the {ordinal(i)} layer"), call = I(layers[[i]]$constructor), parent = cnd) + cli::cli_abort(c("Problem while {step}.", "i" = "Error occurred in the {ordinal(i)} layer."), call = I(layers[[i]]$constructor), parent = cnd) } ) out From 5091d15f3e394e732b4e3c8b51f72e62fa3b94d5 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Tue, 24 May 2022 14:15:32 +0200 Subject: [PATCH 8/8] update error snapshots --- tests/testthat/_snaps/annotate.md | 8 ++++---- tests/testthat/_snaps/geom-.md | 4 ++-- tests/testthat/_snaps/geom-linerange.md | 4 ++-- tests/testthat/_snaps/geom-path.md | 4 ++-- tests/testthat/_snaps/geom-raster.md | 4 ++-- tests/testthat/_snaps/geom-ribbon.md | 12 ++++++------ tests/testthat/_snaps/geom-sf.md | 4 ++-- tests/testthat/_snaps/geom-violin.md | 8 ++++---- tests/testthat/_snaps/layer.md | 16 ++++++++-------- tests/testthat/_snaps/position-jitterdodge.md | 4 ++-- tests/testthat/_snaps/stat-bin.md | 16 ++++++++-------- tests/testthat/_snaps/stat-boxplot.md | 4 ++-- tests/testthat/_snaps/stat-count.md | 8 ++++---- tests/testthat/_snaps/stat-density.md | 4 ++-- tests/testthat/_snaps/stat-density2d.md | 4 ++-- tests/testthat/_snaps/stat-ecdf.md | 4 ++-- 16 files changed, 54 insertions(+), 54 deletions(-) diff --git a/tests/testthat/_snaps/annotate.md b/tests/testthat/_snaps/annotate.md index 49bdbae686..ed67a8d029 100644 --- a/tests/testthat/_snaps/annotate.md +++ b/tests/testthat/_snaps/annotate.md @@ -1,14 +1,14 @@ # annotation_raster() and annotation_custom() requires cartesian coordinates - Problem converting geom to grob - i Error occurred in the 1st layer + Problem while converting geom to grob. + i Error occurred in the 1st layer. Caused by error in `draw_panel()`: ! `annotation_raster()` only works with `coord_cartesian()` --- - Problem converting geom to grob - i Error occurred in the 1st layer + Problem while converting geom to grob. + i Error occurred in the 1st layer. Caused by error in `draw_panel()`: ! `annotation_custom()` only works with `coord_cartesian()` diff --git a/tests/testthat/_snaps/geom-.md b/tests/testthat/_snaps/geom-.md index 5b1a09893b..46be5c85c3 100644 --- a/tests/testthat/_snaps/geom-.md +++ b/tests/testthat/_snaps/geom-.md @@ -1,7 +1,7 @@ # aesthetic checking in geom throws correct errors - Problem setting up geom aesthetics - i Error occurred in the 1st layer + Problem while setting up geom aesthetics. + i Error occurred in the 1st layer. Caused by error in `use_defaults()`: ! Aesthetic modifiers returned invalid values x The following mappings are invalid diff --git a/tests/testthat/_snaps/geom-linerange.md b/tests/testthat/_snaps/geom-linerange.md index c4aba72fee..840ed7d604 100644 --- a/tests/testthat/_snaps/geom-linerange.md +++ b/tests/testthat/_snaps/geom-linerange.md @@ -1,7 +1,7 @@ # geom_linerange request the right aesthetics - Problem setting up geom - i Error occurred in the 1st layer + Problem while setting up geom. + i Error occurred in the 1st layer. Caused by error in `compute_geom_1()`: ! `geom_linerange()` requires the following missing aesthetics: ymax or xmin and xmax diff --git a/tests/testthat/_snaps/geom-path.md b/tests/testthat/_snaps/geom-path.md index 8faf36169e..af6d86df60 100644 --- a/tests/testthat/_snaps/geom-path.md +++ b/tests/testthat/_snaps/geom-path.md @@ -1,7 +1,7 @@ # geom_path() throws meaningful error on bad combination of varying aesthetics - Problem converting geom to grob - i Error occurred in the 1st layer + Problem while converting geom to grob. + i Error occurred in the 1st layer. Caused by error in `draw_panel()`: ! `geom_path()` can't have varying colour, size, and/or alpha along the line when linetype isn't solid diff --git a/tests/testthat/_snaps/geom-raster.md b/tests/testthat/_snaps/geom-raster.md index 472621c042..37115972d2 100644 --- a/tests/testthat/_snaps/geom-raster.md +++ b/tests/testthat/_snaps/geom-raster.md @@ -16,8 +16,8 @@ --- - Problem converting geom to grob - i Error occurred in the 1st layer + Problem while converting geom to grob. + i Error occurred in the 1st layer. Caused by error in `draw_panel()`: ! `geom_raster()` only works with `coord_cartesian()` diff --git a/tests/testthat/_snaps/geom-ribbon.md b/tests/testthat/_snaps/geom-ribbon.md index 0521405dae..af4c34752f 100644 --- a/tests/testthat/_snaps/geom-ribbon.md +++ b/tests/testthat/_snaps/geom-ribbon.md @@ -1,21 +1,21 @@ # geom_ribbon() checks the aesthetics - Problem setting up geom - i Error occurred in the 1st layer + Problem while setting up geom. + i Error occurred in the 1st layer. Caused by error in `setup_data()`: ! Either xmin or xmax must be given as an aesthetic. --- - Problem setting up geom - i Error occurred in the 1st layer + Problem while setting up geom. + i Error occurred in the 1st layer. Caused by error in `setup_data()`: ! Either ymin or ymax must be given as an aesthetic. --- - Problem converting geom to grob - i Error occurred in the 1st layer + Problem while converting geom to grob. + i Error occurred in the 1st layer. Caused by error in `draw_group()`: ! Aesthetics can not vary along a ribbon diff --git a/tests/testthat/_snaps/geom-sf.md b/tests/testthat/_snaps/geom-sf.md index b9c09fda3d..b65a327f8a 100644 --- a/tests/testthat/_snaps/geom-sf.md +++ b/tests/testthat/_snaps/geom-sf.md @@ -1,7 +1,7 @@ # errors are correctly triggered - Problem converting geom to grob - i Error occurred in the 1st layer + Problem while converting geom to grob. + i Error occurred in the 1st layer. Caused by error in `draw_panel()`: ! `geom_sf()` can only be used with `coord_sf()` diff --git a/tests/testthat/_snaps/geom-violin.md b/tests/testthat/_snaps/geom-violin.md index e3608a86c2..fff4046b0d 100644 --- a/tests/testthat/_snaps/geom-violin.md +++ b/tests/testthat/_snaps/geom-violin.md @@ -1,14 +1,14 @@ # quantiles fails outside 0-1 bound - Problem converting geom to grob - i Error occurred in the 1st layer + Problem while converting geom to grob. + i Error occurred in the 1st layer. Caused by error in `draw_group()`: ! `draw_quantiles` must be between 0 and 1 --- - Problem converting geom to grob - i Error occurred in the 1st layer + Problem while converting geom to grob. + i Error occurred in the 1st layer. Caused by error in `draw_group()`: ! `draw_quantiles` must be between 0 and 1 diff --git a/tests/testthat/_snaps/layer.md b/tests/testthat/_snaps/layer.md index a3c62a08dd..9e7388aebf 100644 --- a/tests/testthat/_snaps/layer.md +++ b/tests/testthat/_snaps/layer.md @@ -29,8 +29,8 @@ # invalid aesthetics throws errors - Problem computing aesthetics - i Error occurred in the 1st layer + Problem while computing aesthetics. + i Error occurred in the 1st layer. Caused by error in `compute_aesthetics()`: ! Aesthetics are not valid data columns. x The following aesthetics are invalid: @@ -39,8 +39,8 @@ --- - Problem mapping statistics to aesthetics - i Error occurred in the 1st layer + Problem while mapping stat to aesthetics. + i Error occurred in the 1st layer. Caused by error in `map_statistic()`: ! Aesthetics must be valid computed stats. x The following aesthetics are invalid: @@ -49,8 +49,8 @@ # function aesthetics are wrapped with stat() - Problem computing aesthetics - i Error occurred in the 1st layer + Problem while computing aesthetics. + i Error occurred in the 1st layer. Caused by error in `compute_aesthetics()`: ! Aesthetics are not valid data columns. x The following aesthetics are invalid: @@ -60,8 +60,8 @@ # computed stats are in appropriate layer - Problem mapping statistics to aesthetics - i Error occurred in the 1st layer + Problem while mapping stat to aesthetics. + i Error occurred in the 1st layer. Caused by error in `map_statistic()`: ! Aesthetics must be valid computed stats. x The following aesthetics are invalid: diff --git a/tests/testthat/_snaps/position-jitterdodge.md b/tests/testthat/_snaps/position-jitterdodge.md index 485d8bbf02..068f546f5b 100644 --- a/tests/testthat/_snaps/position-jitterdodge.md +++ b/tests/testthat/_snaps/position-jitterdodge.md @@ -1,7 +1,7 @@ # position_jitterdodge() fails with meaningful error - Problem computing positions - i Error occurred in the 1st layer + Problem while computing position. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `position_jitterdodge()` requires at least one aesthetic to dodge by diff --git a/tests/testthat/_snaps/stat-bin.md b/tests/testthat/_snaps/stat-bin.md index aabdc610f2..d6a7ca7440 100644 --- a/tests/testthat/_snaps/stat-bin.md +++ b/tests/testthat/_snaps/stat-bin.md @@ -1,21 +1,21 @@ # stat_bin throws error when wrong combination of aesthetic is present - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `stat_bin()` requires an x or y aesthetic. --- - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `stat_bin()` must only have an x or y aesthetic. --- - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `stat_bin()` requires a continuous x aesthetic x the x aesthetic is discrete. @@ -55,8 +55,8 @@ # stat_count throws error when both x and y aesthetic present - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `stat_count()` must only have an x or y aesthetic. diff --git a/tests/testthat/_snaps/stat-boxplot.md b/tests/testthat/_snaps/stat-boxplot.md index 2e930ca60b..1f54101fdc 100644 --- a/tests/testthat/_snaps/stat-boxplot.md +++ b/tests/testthat/_snaps/stat-boxplot.md @@ -8,8 +8,8 @@ # stat_boxplot errors with missing x/y aesthetics - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `stat_boxplot()` requires an x or y aesthetic. diff --git a/tests/testthat/_snaps/stat-count.md b/tests/testthat/_snaps/stat-count.md index fb62f3233b..51d990c52e 100644 --- a/tests/testthat/_snaps/stat-count.md +++ b/tests/testthat/_snaps/stat-count.md @@ -1,14 +1,14 @@ # stat_count() checks the aesthetics - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `stat_count()` requires an x or y aesthetic. --- - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `stat_count()` must only have an x or y aesthetic. diff --git a/tests/testthat/_snaps/stat-density.md b/tests/testthat/_snaps/stat-density.md index 66dce9699a..ef29bcb937 100644 --- a/tests/testthat/_snaps/stat-density.md +++ b/tests/testthat/_snaps/stat-density.md @@ -1,7 +1,7 @@ # stat_density works in both directions - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `stat_density()` requires an x or y aesthetic. diff --git a/tests/testthat/_snaps/stat-density2d.md b/tests/testthat/_snaps/stat-density2d.md index 0aafb0754b..c1bf610cc0 100644 --- a/tests/testthat/_snaps/stat-density2d.md +++ b/tests/testthat/_snaps/stat-density2d.md @@ -1,7 +1,7 @@ # stat_density2d can produce contour and raster data - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `compute_layer()`: ! Invalid value of `contour_var` ("abcd") i Supported values are "density", "ndensity", and "count". diff --git a/tests/testthat/_snaps/stat-ecdf.md b/tests/testthat/_snaps/stat-ecdf.md index 74b2187ce3..e4da4c47f9 100644 --- a/tests/testthat/_snaps/stat-ecdf.md +++ b/tests/testthat/_snaps/stat-ecdf.md @@ -1,7 +1,7 @@ # stat_ecdf works in both directions - Problem computing statistics - i Error occurred in the 1st layer + Problem while computing stat. + i Error occurred in the 1st layer. Caused by error in `setup_params()`: ! `stat_ecdf()` requires an x or y aesthetic.