diff --git a/NEWS.md b/NEWS.md index de3e87cee3..3d0ba28e83 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # ggplot2 (development version) +* `position_jitterdodge()` now dodges by `group` (@teunbrand, #3656) * The `arrow.fill` parameter is now applied to more line-based functions: `geom_path()`, `geom_line()`, `geom_step()` `geom_function()`, line geometries in `geom_sf()` and `element_line()`. diff --git a/R/position-jitterdodge.R b/R/position-jitterdodge.R index fba28a47fa..768f3d8385 100644 --- a/R/position-jitterdodge.R +++ b/R/position-jitterdodge.R @@ -47,21 +47,14 @@ PositionJitterdodge <- ggproto("PositionJitterdodge", Position, flipped_aes <- has_flipped_aes(data) data <- flip_data(data, flipped_aes) width <- self$jitter.width %||% (resolution(data$x, zero = FALSE, TRUE) * 0.4) - # Adjust the x transformation based on the number of 'dodge' variables - possible_dodge <- c("fill", "colour", "linetype", "shape", "size", "alpha") - dodgecols <- intersect(possible_dodge, colnames(data)) - if (length(dodgecols) == 0) { - cli::cli_abort(c( - "{.fn position_jitterdodge} requires at least one aesthetic to dodge by.", - i = "Use one of {.or {.val {possible_dodge}}} aesthetics." - )) - } - ndodge <- lapply(data[dodgecols], levels) # returns NULL for numeric, i.e. non-dodge layers - ndodge <- vec_unique_count(unlist(ndodge)) + + ndodge <- vec_unique(data[c("group", "PANEL", "x")]) + ndodge <- vec_group_id(ndodge[c("PANEL", "x")]) + ndodge <- max(tabulate(ndodge, attr(ndodge, "n"))) list( - dodge.width = self$dodge.width, - jitter.height = self$jitter.height, + dodge.width = self$dodge.width %||% 0.75, + jitter.height = self$jitter.height %||% 0, jitter.width = width / (ndodge + 2), seed = self$seed, flipped_aes = flipped_aes diff --git a/tests/testthat/_snaps/position-jitterdodge.md b/tests/testthat/_snaps/position-jitterdodge.md deleted file mode 100644 index 1a387e880e..0000000000 --- a/tests/testthat/_snaps/position-jitterdodge.md +++ /dev/null @@ -1,8 +0,0 @@ -# position_jitterdodge() fails with meaningful error - - 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. - i Use one of "fill", "colour", "linetype", "shape", "size", or "alpha" aesthetics. - diff --git a/tests/testthat/test-position-jitterdodge.R b/tests/testthat/test-position-jitterdodge.R index 49e8378666..fb3274e61a 100644 --- a/tests/testthat/test-position-jitterdodge.R +++ b/tests/testthat/test-position-jitterdodge.R @@ -1,8 +1,3 @@ -test_that("position_jitterdodge() fails with meaningful error", { - p <- ggplot(mtcars) + geom_point(aes(disp, mpg), position = 'jitterdodge') - expect_snapshot_error(ggplot_build(p)) -}) - test_that("position_jitterdodge preserves widths", { ld <- layer_data( ggplot(mtcars, aes(factor(cyl), fill = factor(am))) +