Skip to content

Commit 3d88c7a

Browse files
authored
Variable sizes for geom_hex() (#6729)
* fix early exit * exploit `hexbin::hexcoords(n)` arg * add `radius` aesthetic * use `radius` in hexagon construction * add example * add test * add news bullet
1 parent 443660a commit 3d88c7a

File tree

5 files changed

+86
-6
lines changed

5 files changed

+86
-6
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
`grid::curveGrob()` (@fmarotta, #5998).
1010
* Fixed a regression where default `width` was miscalculated when some panels
1111
are empty (@teunbrand, #6758)
12+
* `geom_hex()` has a new `radius` aesthetic, representing the relative size of
13+
the hexagons (@teunbrand, #6727)
1214

1315
# ggplot2 4.0.1
1416

R/geom-hex.R

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
GeomHex <- ggproto("GeomHex", Geom,
66
draw_group = function(self, data, panel_params, coord, lineend = "butt",
77
linejoin = "mitre", linemitre = 10) {
8-
data <- fix_linewidth(data, snake_class(self))
98
if (empty(data)) {
109
return(zeroGrob())
1110
}
11+
data <- fix_linewidth(data, snake_class(self))
1212

1313
# Get hex sizes
1414
if (!is.null(data$width)) {
@@ -25,13 +25,12 @@ GeomHex <- ggproto("GeomHex", Geom,
2525
dy <- resolution(data$y, FALSE, TRUE) / sqrt(3) / 2 * 1.15
2626
}
2727

28-
hexC <- hexbin::hexcoords(dx, dy, n = 1)
29-
3028
n <- nrow(data)
29+
hexC <- hexbin::hexcoords(dx, dy, n = n)
3130

32-
hexdata <- data[rep(seq_len(n), each = 6), c("x", "y")]
33-
hexdata$x <- rep.int(hexC$x, n) + hexdata$x
34-
hexdata$y <- rep.int(hexC$y, n) + hexdata$y
31+
hexdata <- vec_rep_each(data[c("x", "y", "radius")], times = 6L)
32+
hexdata$x <- hexC$x * hexdata$radius + hexdata$x
33+
hexdata$y <- hexC$y * hexdata$radius + hexdata$y
3534

3635
coords <- coord$transform(hexdata, panel_params)
3736

@@ -58,6 +57,7 @@ GeomHex <- ggproto("GeomHex", Geom,
5857
fill = from_theme(fill %||% col_mix(ink, paper)),
5958
linewidth = from_theme(borderwidth),
6059
linetype = from_theme(bordertype),
60+
radius = 1,
6161
alpha = NA
6262
),
6363

@@ -95,5 +95,8 @@ GeomHex <- ggproto("GeomHex", Geom,
9595
#' # Or by specifying the width of the bins
9696
#' d + geom_hex(binwidth = c(1, 1000))
9797
#' d + geom_hex(binwidth = c(.1, 500))
98+
#'
99+
#' # The hexagons can be scaled by tuning the radius aesthetic
100+
#' d + geom_hex(aes(radius = after_stat(ncount)))
98101
#' }
99102
geom_hex <- make_constructor(GeomHex, stat = 'binhex')

man/geom_hex.Rd

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

tests/testthat/test-geom-hex.R

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ test_that("bin size are picked up from stat", {
2727
geom_hex(aes(x = x, y = y), binwidth = c(0.1, 0.1)) +
2828
coord_cartesian(xlim = c(-1, 1), ylim = c(-1, 1))
2929
)
30+
31+
expect_doppelganger(
32+
"hexes with different sizes",
33+
ggplot(data.frame(x = 1:3, y = 0, r = (1:3)/6)) +
34+
geom_hex(
35+
aes(x = x, y = y, radius = r),
36+
stat = "identity"
37+
) +
38+
coord_cartesian(xlim = c(0, 4), y = c(-1, 1))
39+
)
40+
3041
})
3142

3243
test_that("geom_hex works in non-linear coordinate systems", {

0 commit comments

Comments
 (0)