2222# ' @param breaks Alternatively, you can supply a numeric vector giving
2323# ' the bin boundaries. Overrides `binwidth`, `bins`, `center`,
2424# ' and `boundary`. Can also be a function that takes group-wise values as input and returns bin boundaries.
25+ # ' @param follow.scale Alternatively, the bin edges can be copied from the scale
26+ # ' breaks, either `"major"` or `"minor"`. Ignored when `"off"`. Note that if
27+ # . the scale's limits are updated by other layers or expansions then its
28+ # . breaks are recomputed and might end up different to the value copied for
29+ # . the bin edges. This is not an issue when the scale uses a fixed breaks
30+ # . vector.
2531# ' @param closed One of `"right"` or `"left"` indicating whether right
2632# ' or left edges of bins are included in the bin.
2733# ' @param pad If `TRUE`, adds empty bins at either end of x. This ensures
@@ -58,8 +64,8 @@ stat_bin <- function(mapping = NULL, data = NULL,
5864 breaks = NULL ,
5965 closed = c(" right" , " left" ),
6066 pad = FALSE ,
67+ follow.scale = c(" off" , " minor" , " major" ),
6168 na.rm = FALSE ,
62- follow.scale = FALSE ,
6369 keep.zeroes = " all" ,
6470 orientation = NA ,
6571 show.legend = NA ,
@@ -81,8 +87,8 @@ stat_bin <- function(mapping = NULL, data = NULL,
8187 breaks = breaks ,
8288 closed = closed ,
8389 pad = pad ,
84- na.rm = na.rm ,
8590 follow.scale = follow.scale ,
91+ na.rm = na.rm ,
8692 orientation = orientation ,
8793 keep.zeroes = keep.zeroes ,
8894 ...
@@ -138,7 +144,15 @@ StatBin <- ggproto("StatBin", Stat,
138144 cli :: cli_abort(" Only one of {.arg boundary} and {.arg center} may be specified in {.fn {snake_class(self)}}." )
139145 }
140146
141- if (is.null(params $ breaks ) && is.null(params $ binwidth ) && is.null(params $ bins )) {
147+ if (! is.null(params $ follow.scale )) {
148+ params $ follow.scale <- match.arg(params $ follow.scale , c(" off" , " minor" , " major" ))
149+ if (params $ follow.scale == " off" ) params $ follow.scale <- NULL
150+ }
151+ if (! is.null(params $ follow.scale ) && ! is.null(params $ breaks )) {
152+ cli :: cli_abort(" Only one of {.arg follow.scale} and {.arg breaks} may be specified in {.fn {snake_class(self)}}." )
153+ }
154+
155+ if (is.null(params $ breaks ) && is.null(params $ binwidth ) && is.null(params $ bins ) && is.null(params $ follow.scale )) {
142156 cli :: cli_inform(" {.fn {snake_class(self)}} using {.code bins = 30}. Pick better value with {.arg binwidth}." )
143157 params $ bins <- 30
144158 }
@@ -152,13 +166,15 @@ StatBin <- ggproto("StatBin", Stat,
152166 center = NULL , boundary = NULL ,
153167 closed = c(" right" , " left" ), pad = FALSE ,
154168 breaks = NULL , flipped_aes = FALSE , keep.zeroes = " all" ,
155- follow.scale = FALSE ,
169+ follow.scale = NULL ,
156170 # The following arguments are not used, but must
157171 # be listed so parameters are computed correctly
158172 origin = NULL , right = NULL , drop = NULL ) {
159173 x <- flipped_names(flipped_aes )$ x
160- if (follow.scale ) {
161- breaks <- scales [[x ]]$ get_breaks()
174+ if (! is.null(follow.scale )) {
175+ breaks <- switch (follow.scale ,
176+ minor = scales [[x ]]$ get_breaks_minor(),
177+ major = scales [[x ]]$ get_breaks())
162178 bins <- bin_breaks(breaks , closed )
163179 } else if (! is.null(breaks )) {
164180 if (is.function(breaks )) {
0 commit comments