diff --git a/NEWS.md b/NEWS.md index d5f353a41a..23a49eedf3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -47,6 +47,8 @@ * `stat_bin()` will now error when the number of bins exceeds 1e6 to avoid accidentally freezing the user session (@thomasp85). +* `stat_bin()` now handles data with only one unique value (@yutannihilation #3047). + # ggplot2 3.1.0 ## Breaking changes diff --git a/R/bin.R b/R/bin.R index 62daa79575..a5e7ae85bc 100644 --- a/R/bin.R +++ b/R/bin.R @@ -101,6 +101,9 @@ bin_breaks_bins <- function(x_range, bins = 30, center = NULL, bins <- as.integer(bins) if (bins < 1) { stop("Need at least one bin.", call. = FALSE) + } else if (zero_range(x_range)) { + # 0.1 is the same width as the expansion `expand_default()` gives for 0-width data + width <- 0.1 } else if (bins == 1) { width <- diff(x_range) boundary <- x_range[1] diff --git a/tests/testthat/test-stat-bin.R b/tests/testthat/test-stat-bin.R index 902ccd313d..5e70617b8b 100644 --- a/tests/testthat/test-stat-bin.R +++ b/tests/testthat/test-stat-bin.R @@ -69,6 +69,15 @@ test_that("breaks are transformed by the scale", { expect_equal(out2$xmin, sqrt(c(1, 2.5))) }) +test_that("geom_histogram() can be drawn over a 0-width range (#3043)", { + df <- data_frame(x = rep(1, 100)) + out <- layer_data(ggplot(df, aes(x)) + geom_histogram()) + + expect_equal(nrow(out), 1) + expect_equal(out$xmin, 0.95) + expect_equal(out$xmax, 1.05) +}) + # Underlying binning algorithm -------------------------------------------- comp_bin <- function(df, ...) {