Skip to content

Commit 07b7457

Browse files
authored
Make nudging more robust (#2874)
* make nudging more robust. closes #2733. * add regression tests for position_nudge() * simplify position_nudge, remove required aesthetics
1 parent 71cb174 commit 07b7457

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@
5656
* `labs()` now has named arguments `title`, `subtitle`, `caption`, and `tag`.
5757
Also, `labs()` now accepts tidyeval (@yutannihilation, #2669).
5858

59+
* `position_nudge()` is now more robust and nudges only in the direction
60+
requested. This enables, for example, the horizontal nudging of boxplots
61+
(@clauswilke, #2733).
62+
5963
# ggplot2 3.0.0
6064

6165
## Breaking changes

R/position-nudge.R

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,22 @@ PositionNudge <- ggproto("PositionNudge", Position,
4141
x = 0,
4242
y = 0,
4343

44-
required_aes = c("x", "y"),
45-
4644
setup_params = function(self, data) {
4745
list(x = self$x, y = self$y)
4846
},
4947

5048
compute_layer = function(data, params, panel) {
51-
transform_position(data, function(x) x + params$x, function(y) y + params$y)
49+
# transform only the dimensions for which non-zero nudging is requested
50+
if (params$x != 0) {
51+
if (params$y != 0) {
52+
transform_position(data, function(x) x + params$x, function(y) y + params$y)
53+
} else {
54+
transform_position(data, function(x) x + params$x, NULL)
55+
}
56+
} else if (params$y != 0) {
57+
transform_position(data, NULL, function(y) y + params$y)
58+
} else {
59+
data # if both x and y are 0 we don't need to transform
60+
}
5261
}
5362
)

tests/testthat/test-position-nudge.R

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
context("position_nudge")
2+
3+
test_that("nudging works in both dimensions simultaneously", {
4+
df <- data.frame(x = 1:3)
5+
6+
p <- ggplot(df, aes(x, x, xmax = x, xmin = x, ymax = x, ymin = x)) +
7+
geom_point(position = position_nudge(x = 1, y = 2))
8+
9+
data <- layer_data(p)
10+
11+
expect_equal(data$x, 2:4)
12+
expect_equal(data$xmin, 2:4)
13+
expect_equal(data$xmax, 2:4)
14+
expect_equal(data$y, 3:5)
15+
expect_equal(data$ymin, 3:5)
16+
expect_equal(data$ymax, 3:5)
17+
})
18+
19+
test_that("nudging works in individual dimensions", {
20+
df <- data.frame(x = 1:3)
21+
22+
# nudging in x
23+
# use an empty layer so can test individual aesthetics
24+
p <- ggplot(df, aes(x = x, xmax = x, xmin = x)) +
25+
layer(geom = Geom, stat = StatIdentity, position = position_nudge(x = 1))
26+
27+
data <- layer_data(p)
28+
29+
expect_equal(data$x, 2:4)
30+
expect_equal(data$xmin, 2:4)
31+
expect_equal(data$xmax, 2:4)
32+
33+
# nudging in y
34+
# use an empty layer so can test individual aesthetics
35+
p <- ggplot(df, aes(y = x, ymax = x, ymin = x)) +
36+
layer(geom = Geom, stat = StatIdentity, position = position_nudge(y = 2))
37+
38+
data <- layer_data(p)
39+
40+
expect_equal(data$y, 3:5)
41+
expect_equal(data$ymin, 3:5)
42+
expect_equal(data$ymax, 3:5)
43+
})

0 commit comments

Comments
 (0)