Skip to content

Allow functional limits in continuous scales #2334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 24, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ core developer team.
equivalents.

* `geom_polygon()` can now draw polygons with holes using the new `subgroup`
aesthetic. This functionality requires R 3.6.0 (@thomasp85, #3128)
aesthetic. This functionality requires R 3.6.0 (@thomasp85, #3128).

* Aesthetic mappings now accept functions that return `NULL` (@yutannihilation,
#2997).
Expand All @@ -46,12 +46,17 @@ core developer team.
interest to extension developers (@clauswilke, #2872).

* `x0` and `y0` are now recognized positional aesthetics so they will get scaled
if used in extension geoms and stats (@thomasp85, #3168)
if used in extension geoms and stats (@thomasp85, #3168).

* Continuous scale limits now accept functions which accept the default
limits and return adjusted limits. This makes it possible to write
a function that e.g. ensures the limits are always a multiple of 100,
regardless of the data (@econandrew, #2307).

## Minor improvements and bug fixes

* `cut_width()` now accepts `...` to pass further arguments to `base::cut.default()`
like `cut_number()` and `cut_interval()` already did (@cderv, #3055)
like `cut_number()` and `cut_interval()` already did (@cderv, #3055).

* `coord_map()` now can have axes on the top and right (@karawoo, #3042).

Expand Down Expand Up @@ -83,7 +88,7 @@ core developer team.

* `geom_area()` and `geom_ribbon()` now sort the data along the x-axis in the
`setup_data()` method rather than as part of `draw_group()` (@thomasp85,
#3023)
#3023).

* `geom_hline()`, `geom_vline()`, and `geom_abline()` now throw a warning if the
user supplies both an `xintercept`, `yintercept`, or `slope` value and a
Expand All @@ -106,7 +111,7 @@ core developer team.
#3079).

* `scale_shape_identity()` now works correctly with `guide = "legend"`
(@malcolmbarrett, #3029)
(@malcolmbarrett, #3029).

* `stat_bin()` will now error when the number of bins exceeds 1e6 to avoid
accidentally freezing the user session (@thomasp85).
Expand All @@ -116,8 +121,7 @@ core developer team.
* `facet_wrap()` and `facet_grid()` now automatically remove NULL from facet
specs, and accept empty specs (@yutannihilation, #3070, #2986).

* `stat_bin()` now handles data with only one unique value (@yutannihilation
#3047).
* `stat_bin()` now handles data with only one unique value (@yutannihilation, #3047).

* `sec_axis()` now accepts functions as well as formulas (@yutannihilation, #3031).

Expand Down
23 changes: 15 additions & 8 deletions R/scale-.r
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
Scale <- ggproto("Scale", NULL,

call = NULL,

aesthetics = aes(),
scale_name = NULL,
palette = function() {
Expand Down Expand Up @@ -107,16 +106,20 @@ Scale <- ggproto("Scale", NULL,
stop("Not implemented", call. = FALSE)
},

# if scale is a function, apply it to the default (inverted) scale range
# if scale contains a NULL, use the default scale range
# if scale contains a NA, use the default range for that axis, otherwise
# use the user defined limit for that axis
get_limits = function(self) {
if (self$is_empty()) return(c(0, 1))

if (!is.null(self$limits)) {
ifelse(!is.na(self$limits), self$limits, self$range$range)
} else {
if (is.null(self$limits)) {
self$range$range
} else if (is.function(self$limits)) {
# if limits is a function, it expects to work in data space
self$trans$transform(self$limits(self$trans$inverse(self$range$range)))
} else {
ifelse(is.na(self$limits), self$range$range, self$limits)
}
},

Expand Down Expand Up @@ -526,8 +529,12 @@ ScaleDiscrete <- ggproto("ScaleDiscrete", Scale,
#' - A character vector giving labels (must be same length as `breaks`)
#' - A function that takes the breaks as input and returns labels
#' as output
#' @param limits A numeric vector of length two providing limits of the scale.
#' Use `NA` to refer to the existing minimum or maximum.
#' @param limits One of:
#' - `NULL` to use the default scale range
#' - A numeric vector of length two providing limits of the scale.
#' Use `NA` to refer to the existing minimum or maximum
#' - A function that accepts the existing (automatic) limits and returns
#' new limits
#' @param rescaler Used by diverging and n colour gradients
#' (i.e. [scale_colour_gradient2()], [scale_colour_gradientn()]).
#' A function used to scale the input values to the range \[0, 1].
Expand All @@ -538,7 +545,7 @@ ScaleDiscrete <- ggproto("ScaleDiscrete", Scale,
#' @param trans Either the name of a transformation object, or the
#' object itself. Built-in transformations include "asn", "atanh",
#' "boxcox", "date", "exp", "hms", "identity", "log", "log10", "log1p", "log2",
#' "logit", "modulus", "probability", "probit", "pseudo_log", "reciprocal",
#' "logit", "modulus", "probability", "probit", "pseudo_log", "reciprocal",
#' "reverse", "sqrt" and "time".
#'
#' A transformation object bundles together a transform, its inverse,
Expand Down Expand Up @@ -569,7 +576,7 @@ continuous_scale <- function(aesthetics, scale_name, palette, name = waiver(),
}

trans <- as.trans(trans)
if (!is.null(limits)) {
if (!is.null(limits) && !is.function(limits)) {
limits <- trans$transform(limits)
}

Expand Down
10 changes: 8 additions & 2 deletions man/continuous_scale.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions man/scale_continuous.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions man/scale_date.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions man/scale_gradient.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 16 additions & 4 deletions man/scale_size.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading