Skip to content

Commit 101c68d

Browse files
authored
fixes #3879 (#3976)
1 parent 8a3f711 commit 101c68d

File tree

5 files changed

+20
-8
lines changed

5 files changed

+20
-8
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
* `stat_function()` now works with transformed y axes, e.g. `scale_y_log10()`
1212
(@clauswilke, #3905).
1313

14+
* A bug was fixed in `stat_contour()` when calculating breaks based on
15+
the `bins` argument (@clauswilke, #3879).
16+
1417
* A newly added geom `geom_density_2d_filled()` and associated stat
1518
`stat_density_2d_filled()` can draw filled density contours
1619
(@clauswilke, #3846).

R/geom-contour.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
#' v + geom_contour_filled()
3535
#'
3636
#' # Setting bins creates evenly spaced contours in the range of the data
37+
#' v + geom_contour(bins = 3)
3738
#' v + geom_contour(bins = 5)
38-
#' v + geom_contour(bins = 10)
3939
#'
4040
#' # Setting binwidth does the same thing, parameterised by the distance
4141
#' # between contours

R/stat-contour.r

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,19 +151,26 @@ contour_breaks <- function(z_range, bins = NULL, binwidth = NULL, breaks = NULL)
151151
# If no parameters set, use pretty bins
152152
if (is.null(bins) && is.null(binwidth)) {
153153
breaks <- pretty(z_range, 10)
154+
return(breaks)
154155
}
155156

156157
# If provided, use bins to calculate binwidth
157158
if (!is.null(bins)) {
158159
binwidth <- diff(z_range) / (bins - 1)
159-
}
160-
161-
# If necessary, compute breaks from binwidth
162-
if (is.null(breaks)) {
163160
breaks <- fullseq(z_range, binwidth)
161+
162+
# Sometimes the above sequence yields one bin too few.
163+
# If this happens, try again.
164+
if (length(breaks) < bins + 1) {
165+
binwidth <- diff(z_range) / bins
166+
breaks <- fullseq(z_range, binwidth)
167+
}
168+
169+
return(breaks)
164170
}
165171

166-
breaks
172+
# if we haven't returned yet, compute breaks from binwidth
173+
fullseq(z_range, binwidth)
167174
}
168175

169176
#' Compute isoband objects

man/geom_contour.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-contour.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ test_that("contour breaks can be set manually and by bins and binwidth", {
3636
range <- c(0, 1)
3737
expect_equal(contour_breaks(range), pretty(range, 10))
3838
expect_identical(contour_breaks(range, breaks = 1:3), 1:3)
39-
expect_length(contour_breaks(range, bins = 5), 5)
39+
expect_length(contour_breaks(range, bins = 5), 6)
40+
# shifting the range by 0.2 hits another execution branch in contour_breaks()
41+
expect_length(contour_breaks(range + 0.2, bins = 5), 6)
4042
expect_equal(resolution(contour_breaks(range, binwidth = 0.3)), 0.3)
4143
})
4244

0 commit comments

Comments
 (0)