Skip to content

Commit 49b45c1

Browse files
authored
Apply jitter in position_jitterdodge() once (#5819)
* Follow #4403 * add test * add news bullet
1 parent 6f60766 commit 49b45c1

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@
7979
returns input unaltered (@teunbrand, #5800).
8080
* `width` is implemented as aesthetic instead of parameter in `geom_col()` and
8181
`geom_bar()` (#3142).
82+
* Fix a bug in `position_jitterdodge()` where different jitters would be applied
83+
to different position aesthetics of the same axis (@teunbrand, #5818).
8284

8385
# ggplot2 3.5.1
8486

R/position-jitterdodge.R

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,18 @@ PositionJitterdodge <- ggproto("PositionJitterdodge", Position,
7676
trans_x <- if (params$jitter.width > 0) function(x) jitter(x, amount = params$jitter.width)
7777
trans_y <- if (params$jitter.height > 0) function(x) jitter(x, amount = params$jitter.height)
7878

79-
data <- with_seed_null(params$seed, transform_position(data, trans_x, trans_y))
79+
x_aes <- intersect(ggplot_global$x_aes, names(data))
80+
y_aes <- intersect(ggplot_global$y_aes, names(data))
81+
82+
x <- if (length(x_aes) == 0) 0 else data[[x_aes[1]]]
83+
y <- if (length(y_aes) == 0) 0 else data[[y_aes[1]]]
84+
dummy_data <- data_frame0(x = x, y = y, .size = nrow(data))
85+
86+
fixed_jitter <- with_seed_null(params$seed, transform_position(dummy_data, trans_x, trans_y))
87+
x_jit <- fixed_jitter$x - x
88+
y_jit <- fixed_jitter$y - y
89+
90+
data <- transform_position(data, function(x) x + x_jit, function(x) x + y_jit)
8091
flip_data(data, params$flipped_aes)
8192
}
8293
)

tests/testthat/test-position-jitterdodge.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,15 @@ test_that("position_jitterdodge() fails with meaningful error", {
22
p <- ggplot(mtcars) + geom_point(aes(disp, mpg), position = 'jitterdodge')
33
expect_snapshot_error(ggplot_build(p))
44
})
5+
6+
test_that("position_jitterdodge preserves widths", {
7+
ld <- layer_data(
8+
ggplot(mtcars, aes(factor(cyl), fill = factor(am))) +
9+
geom_bar(position = position_jitterdodge())
10+
)
11+
12+
expect_equal(
13+
as.numeric(ld$xmax - ld$xmin),
14+
rep(0.45, nrow(ld))
15+
)
16+
})

0 commit comments

Comments
 (0)