Skip to content

Commit 08e5f6c

Browse files
bjreismanclauswilke
authored andcommitted
Scaled densities/counts in 2d density/bins plots (#2679) (#2680)
* Added scaled statistics to 2d density plots, contour plots, and 2d histograms (bin2d and binhex). * + ggplot2 styling (spaces around "/") + updated documentation (revisions suggested by clauswilke) * Changed where the 'scaled' variable is computed and when it is named to minimize renaming of existing variables. 🎨 * scaled => ndensity - swapped `scaled` for `ndensity` in `stat_density2d()`; - added `ndensity` to `stat_density` as an alias for `scaled`; - added an example to `geom_densityd2()`; - updated NEWS.md to reflect these changes. * updated `test-stat-density` with the addition of `ndensity`. * Fixes #2679 * update docs * documentation cleanups
1 parent 5f49fb4 commit 08e5f6c

15 files changed

+128
-13
lines changed

NEWS.md

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

3+
* `stat_contour()`, `stat_density2d()`, `stat_bin2d()`, `stat_binhex()`
4+
now calculate normalized statistics including `nlevel`, `ndensity`, and
5+
`ncount`. Also, `stat_density()` now includes the calculated statistic
6+
`nlevel`, an aliasfor `scaled`, to better match the syntax of `stat_bin()`
7+
(@bjreisman, #2679).
8+
39
* `geom_hex()` now understands the `size` and `linetype` aesthetics
410
(@mikmart, #2488).
511

R/geom-density2d.r

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@
3030
#' # set of contours for each value of that variable
3131
#' d + geom_density_2d(aes(colour = cut))
3232
#'
33+
#' # Similarly, if you apply faceting to the plot, contours will be
34+
#' # drawn for each facet, but the levels will calculated across all facets
35+
#' d + stat_density_2d(aes(fill = stat(level)), geom = "polygon") +
36+
#' facet_grid(. ~ cut) + scale_fill_viridis_c()
37+
#' # To override this behavior (for instace, to better visualize the density
38+
#' # within each facet), use stat(nlevel)
39+
#' d + stat_density_2d(aes(fill = stat(nlevel)), geom = "polygon") +
40+
#' facet_grid(. ~ cut) + scale_fill_viridis_c()
41+
#'
3342
#' # If we turn contouring off, we can use use geoms like tiles:
3443
#' d + stat_density_2d(geom = "raster", aes(fill = stat(density)), contour = FALSE)
3544
#' # Or points:

R/stat-bin2d.r

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
#' @param drop if `TRUE` removes all cells with 0 counts.
66
#' @export
77
#' @rdname geom_bin2d
8+
#' @section Computed variables:
9+
#' \describe{
10+
#' \item{count}{number of points in bin}
11+
#' \item{density}{density of points in bin, scaled to integrate to 1}
12+
#' \item{ncount}{count, scaled to maximum of 1}
13+
#' \item{ndensity}{density, scaled to maximum of 1}
14+
#' }
815
stat_bin_2d <- function(mapping = NULL, data = NULL,
916
geom = "tile", position = "identity",
1017
...,
@@ -74,7 +81,9 @@ StatBin2d <- ggproto("StatBin2d", Stat,
7481
out$height <- ydim$length
7582

7683
out$count <- out$value
84+
out$ncount <- out$count / max(out$count, na.rm = TRUE)
7785
out$density <- out$count / sum(out$count, na.rm = TRUE)
86+
out$ndensity <- out$density / max(out$density, na.rm = TRUE)
7887
out
7988
}
8089
)

R/stat-binhex.r

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#' @export
22
#' @rdname geom_hex
33
#' @inheritParams stat_bin_2d
4+
#' @section Computed variables:
5+
#' \describe{
6+
#' \item{count}{number of points in bin}
7+
#' \item{density}{density of points in bin, scaled to integrate to 1}
8+
#' \item{ncount}{count, scaled to maximum of 1}
9+
#' \item{ndensity}{density, scaled to maximum of 1}
10+
#' }
411
stat_bin_hex <- function(mapping = NULL, data = NULL,
512
geom = "hex", position = "identity",
613
...,
@@ -48,7 +55,9 @@ StatBinhex <- ggproto("StatBinhex", Stat,
4855
wt <- data$weight %||% rep(1L, nrow(data))
4956
out <- hexBinSummarise(data$x, data$y, wt, binwidth, sum)
5057
out$density <- as.vector(out$value / sum(out$value, na.rm = TRUE))
58+
out$ndensity <- out$density / max(out$density, na.rm = TRUE)
5159
out$count <- out$value
60+
out$ncount <- out$count / max(out$count, na.rm = TRUE)
5261
out$value <- NULL
5362

5463
out

R/stat-contour.r

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#' @section Computed variables:
44
#' \describe{
55
#' \item{level}{height of contour}
6+
#' \item{nlevel}{height of contour, scaled to maximum of 1}
7+
#' \item{piece}{contour piece (an integer)}
68
#' }
79
#' @rdname geom_contour
810
stat_contour <- function(mapping = NULL, data = NULL,
@@ -91,6 +93,7 @@ contour_lines <- function(data, breaks, complete = FALSE) {
9193

9294
data.frame(
9395
level = rep(levels, lengths),
96+
nlevel = rep(levels, lengths) / max(rep(levels, lengths), na.rm = TRUE),
9497
x = xs,
9598
y = ys,
9699
piece = pieces,

R/stat-density-2d.r

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
#' using [MASS::bandwidth.nrd()].
88
#' @section Computed variables:
99
#' Same as [stat_contour()]
10+
#'
11+
#' With the addition of:
12+
#' \describe{
13+
#' \item{density}{the density estimate}
14+
#' \item{ndensity}{density estimate, scaled to maximum of 1}
15+
#' }
1016
stat_density_2d <- function(mapping = NULL, data = NULL,
1117
geom = "density_2d", position = "identity",
1218
...,
@@ -63,9 +69,10 @@ StatDensity2d <- ggproto("StatDensity2d", Stat,
6369
df$group <- data$group[1]
6470

6571
if (contour) {
66-
StatContour$compute_panel(df, scales, bins, binwidth)
72+
StatContour$compute_panel(df, scales, bins, binwidth)
6773
} else {
6874
names(df) <- c("x", "y", "density", "group")
75+
df$ndensity <- df$density / max(df$density, na.rm = TRUE)
6976
df$level <- 1
7077
df$piece <- 1
7178
df

R/stat-density.r

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#' \item{count}{density * number of points - useful for stacked density
2222
#' plots}
2323
#' \item{scaled}{density estimate, scaled to maximum of 1}
24+
#' \item{ndensity}{alias for `scaled`, to mirror the syntax of
25+
#' [`stat_bin()`]}
2426
#' }
2527
#' @export
2628
#' @rdname geom_density
@@ -92,6 +94,7 @@ compute_density <- function(x, w, from, to, bw = "nrd0", adjust = 1,
9294
x = NA_real_,
9395
density = NA_real_,
9496
scaled = NA_real_,
97+
ndensity = NA_real_,
9598
count = NA_real_,
9699
n = NA_integer_
97100
))
@@ -104,6 +107,7 @@ compute_density <- function(x, w, from, to, bw = "nrd0", adjust = 1,
104107
x = dens$x,
105108
density = dens$y,
106109
scaled = dens$y / max(dens$y, na.rm = TRUE),
110+
ndensity = dens$y / max(dens$y, na.rm = TRUE),
107111
count = dens$y * nx,
108112
n = nx
109113
)

man/geom_bin2d.Rd

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

man/geom_contour.Rd

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

man/geom_density.Rd

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

man/geom_density_2d.Rd

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

man/geom_hex.Rd

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

man/ggtheme.Rd

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

man/scale_viridis.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-stat-density.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ test_that("compute_density returns useful df and throws warning when <2 values",
99
expect_warning(dens <- compute_density(1, NULL, from = 0, to = 0))
1010

1111
expect_equal(nrow(dens), 1)
12-
expect_equal(names(dens), c("x", "density", "scaled", "count", "n"))
12+
expect_equal(names(dens), c("x", "density", "scaled", "ndensity", "count", "n"))
1313
expect_type(dens$x, "double")
1414
})

0 commit comments

Comments
 (0)