Skip to content

Commit

Permalink
Binned limits and reverse transform (#5357)
Browse files Browse the repository at this point in the history
* Borrow `get_limits()` method

* Consider sort-order of limits

* Add tests

* Add news bullet
  • Loading branch information
teunbrand committed Aug 1, 2023
1 parent a747da3 commit cd7199d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
6 changes: 5 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# ggplot2 (development version)

* Binned scales now treat `NA`s in limits the same way continuous scales do
(#5355).

* Binned scales work better with `trans = "reverse"` (#5355).

* The `legend.text.align` and `legend.title.align` arguments in `theme()` are
deprecated. The `hjust` setting of the `legend.text` and `legend.title`
elements continues to fulfil the role of text alignment (@teunbrand, #5347).

* Integers are once again valid input to theme arguments that expect numeric
input (@teunbrand, #5369)


* Nicer error messages for xlim/ylim arguments in coord-* functions
(@92amartins, #4601, #5297).

Expand Down
15 changes: 13 additions & 2 deletions R/scale-.R
Original file line number Diff line number Diff line change
Expand Up @@ -1057,10 +1057,16 @@ ScaleBinned <- ggproto("ScaleBinned", Scale,
expand_range4(self$get_limits(), expand)
},

get_limits = function(self) {
ggproto_parent(ScaleContinuous, self)$get_limits()
},

get_breaks = function(self, limits = self$get_limits()) {
if (self$is_empty()) return(numeric())

limits <- self$trans$inverse(limits)
is_rev <- limits[2] < limits[1]
limits <- sort(limits)

if (is.null(self$breaks)) {
return(NULL)
Expand Down Expand Up @@ -1107,7 +1113,11 @@ ScaleBinned <- ggproto("ScaleBinned", Scale,
}
new_limits_trans <- suppressWarnings(self$trans$transform(new_limits))
limits[is.finite(new_limits_trans)] <- new_limits[is.finite(new_limits_trans)]
self$limits <- self$trans$transform(limits)
if (is_rev) {
self$limits <- rev(self$trans$transform(limits))
} else {
self$limits <- self$trans$transform(limits)
}
}
} else if (is.function(self$breaks)) {
if ("n.breaks" %in% names(formals(environment(self$breaks)$f))) {
Expand All @@ -1124,7 +1134,8 @@ ScaleBinned <- ggproto("ScaleBinned", Scale,
}

# Breaks must be within limits
breaks <- breaks[breaks >= limits[1] & breaks <= limits[2]]
breaks <- oob_discard(breaks, sort(limits))

self$breaks <- breaks

self$trans$transform(breaks)
Expand Down
15 changes: 15 additions & 0 deletions tests/testthat/test-scale-binned.R
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ test_that("binned limits should not compute out-of-bounds breaks", {
))
})

test_that("binned scales can use NAs in limits", {
scale <- scale_x_binned(limits = c(NA, 10))
scale$train(c(-20, 20))
expect_equal(scale$get_limits(), c(-20, 10))
scale <- scale_x_binned(limits = c(-10, NA))
scale$train(c(-20, 20))
expect_equal(scale$get_limits(), c(-10, 20))
})

test_that("binned scales can calculate breaks with reverse transformation", {
scale <- scale_x_binned(trans = "reverse")
scale$train(c(1, 9))
expect_equal(scale$get_breaks(), 8:2)
})

test_that('binned scales can calculate breaks on dates', {

data <- seq(as.Date("2000-01-01"), as.Date("2020-01-01"), length.out = 100)
Expand Down

0 comments on commit cd7199d

Please sign in to comment.