Skip to content

Commit 9ced958

Browse files
daniel-wellsyutannihilation
authored andcommitted
add length argument to geom_rug to allow different lengths (#3109)
1 parent 72e04b1 commit 9ced958

File tree

4 files changed

+59
-14
lines changed

4 files changed

+59
-14
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# ggplot2 3.1.0.9000
22

3+
* `geom_rug()` gains a `length` option to allow for changing the length of the rug lines. (@daniel-wells, #3109)
4+
35
* `coord_sf()` graticule lines are now drawn in the same thickness as
46
panel grid lines in `coord_cartesian()`, and seting panel grid
57
lines to `element_blank()` now also works in `coord_sf()`

R/geom-rug.r

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
#' with the two 1d marginal distributions. Rug plots display individual
55
#' cases so are best used with smaller datasets.
66
#'
7-
#' The rug lines are drawn with a fixed size (3\% of the total plot size) so
8-
#' are dependent on the overall scale expansion in order not to overplot
9-
#' existing data.
7+
#' By default, the rug lines are drawn with a length that corresponds to 3\%
8+
#' of the total plot size. Since the default scale expansion of for continuous
9+
#' variables is 5\% at both ends of the scale, the rug will not overlap with
10+
#' any data points under the default settings.
1011
#'
1112
#' @eval rd_aesthetics("geom", "rug")
1213
#' @inheritParams layer
@@ -15,6 +16,7 @@
1516
#' It can be set to a string containing any of `"trbl"`, for top, right,
1617
#' bottom, and left.
1718
#' @param outside logical that controls whether to move the rug tassels outside of the plot area. Default is off (FALSE). You will also need to use `coord_cartesian(clip = "off")`. When set to TRUE, also consider changing the sides argument to "tr". See examples.
19+
#' @param length A [grid::unit()] object that sets the length of the rug lines. Use scale expansion to avoid overplotting of data.
1820
#' @export
1921
#' @examples
2022
#' p <- ggplot(mtcars, aes(wt, mpg)) +
@@ -43,11 +45,17 @@
4345
#' coord_cartesian(clip = "off") +
4446
#' theme(plot.margin = margin(1, 1, 1, 1, "cm"))
4547
#'
48+
#' # increase the line length and
49+
#' # expand axis to avoid overplotting
50+
#' p + geom_rug(length = unit(0.05, "npc")) +
51+
#' scale_y_continuous(expand = c(0.1, 0.1))
52+
#'
4653
geom_rug <- function(mapping = NULL, data = NULL,
4754
stat = "identity", position = "identity",
4855
...,
4956
outside = FALSE,
5057
sides = "bl",
58+
length = unit(0.03, "npc"),
5159
na.rm = FALSE,
5260
show.legend = NA,
5361
inherit.aes = TRUE) {
@@ -62,6 +70,7 @@ geom_rug <- function(mapping = NULL, data = NULL,
6270
params = list(
6371
outside = outside,
6472
sides = sides,
73+
length = length,
6574
na.rm = na.rm,
6675
...
6776
)
@@ -76,7 +85,10 @@ geom_rug <- function(mapping = NULL, data = NULL,
7685
GeomRug <- ggproto("GeomRug", Geom,
7786
optional_aes = c("x", "y"),
7887

79-
draw_panel = function(data, panel_params, coord, sides = "bl", outside) {
88+
draw_panel = function(data, panel_params, coord, sides = "bl", outside = FALSE, length = unit(0.03, "npc")) {
89+
if (!inherits(length, "unit")) {
90+
stop("'length' must be a 'unit' object.", call. = FALSE)
91+
}
8092
rugs <- list()
8193
data <- coord$transform(data, panel_params)
8294

@@ -88,25 +100,25 @@ GeomRug <- ggproto("GeomRug", Geom,
88100

89101
# move the rug to outside the main plot space
90102
rug_length <- if (!outside) {
91-
list(min = 0.03, max = 0.97)
103+
list(min = length, max = unit(1, "npc") - length)
92104
} else {
93-
list(min = -0.03, max = 1.03)
105+
list(min = -1 * length, max = unit(1, "npc") + length)
94106
}
95107

96108
gp <- gpar(col = alpha(data$colour, data$alpha), lty = data$linetype, lwd = data$size * .pt)
97109
if (!is.null(data$x)) {
98110
if (grepl("b", sides)) {
99111
rugs$x_b <- segmentsGrob(
100112
x0 = unit(data$x, "native"), x1 = unit(data$x, "native"),
101-
y0 = unit(0, "npc"), y1 = unit(rug_length$min, "npc"),
113+
y0 = unit(0, "npc"), y1 = rug_length$min,
102114
gp = gp
103115
)
104116
}
105117

106118
if (grepl("t", sides)) {
107119
rugs$x_t <- segmentsGrob(
108120
x0 = unit(data$x, "native"), x1 = unit(data$x, "native"),
109-
y0 = unit(1, "npc"), y1 = unit(rug_length$max, "npc"),
121+
y0 = unit(1, "npc"), y1 = rug_length$max,
110122
gp = gp
111123
)
112124
}
@@ -116,15 +128,15 @@ GeomRug <- ggproto("GeomRug", Geom,
116128
if (grepl("l", sides)) {
117129
rugs$y_l <- segmentsGrob(
118130
y0 = unit(data$y, "native"), y1 = unit(data$y, "native"),
119-
x0 = unit(0, "npc"), x1 = unit(rug_length$min, "npc"),
131+
x0 = unit(0, "npc"), x1 = rug_length$min,
120132
gp = gp
121133
)
122134
}
123135

124136
if (grepl("r", sides)) {
125137
rugs$y_r <- segmentsGrob(
126138
y0 = unit(data$y, "native"), y1 = unit(data$y, "native"),
127-
x0 = unit(1, "npc"), x1 = unit(rug_length$max, "npc"),
139+
x0 = unit(1, "npc"), x1 = rug_length$max,
128140
gp = gp
129141
)
130142
}

man/geom_rug.Rd

Lines changed: 13 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-geom-rug.R

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,25 @@ test_that("coord_flip flips the rugs", {
2020
expect_equal(length(b[[1]]$children[[1]]$y0), 1)
2121
expect_equal(length(b[[1]]$children[[1]]$y1), 1)
2222
})
23+
24+
test_that("Rug length needs unit object", {
25+
p <- ggplot(df, aes(x,y))
26+
expect_error(print(p + geom_rug(length = 0.01)))
27+
})
28+
29+
test_that("Rug lengths are correct", {
30+
a <- layer_grob(p, 2)
31+
32+
# Check default lengths
33+
expect_equal(a[[1]]$children[[1]]$x0, unit(0, "npc"))
34+
expect_equal(a[[1]]$children[[1]]$x1, unit(0.03, "npc"))
35+
36+
p <- ggplot(df, aes(x, y)) + geom_point() + geom_rug(sides = 'l', length = unit(12, "pt"))
37+
b <- layer_grob(p, 2)
38+
39+
# Check default length is changed
40+
expect_equal(a[[1]]$children[[1]]$x0, unit(0, "npc"))
41+
expect_equal(b[[1]]$children[[1]]$x1, unit(12, "pt"))
42+
43+
})
44+

0 commit comments

Comments
 (0)