Skip to content
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

POC bin breaks derived from scale breaks #6174

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
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
Prev Previous commit
Fix default follow.scale inconsistency
arcresu committed Dec 16, 2024
commit d6e536eefc43b1a25db1451b5b3ab6d8f7f62e4c
24 changes: 9 additions & 15 deletions R/stat-bin.R
Original file line number Diff line number Diff line change
@@ -24,10 +24,10 @@
#' and `boundary`. Can also be a function that takes group-wise values as input and returns bin boundaries.
#' @param follow.scale Alternatively, the bin edges can be copied from the scale
#' breaks, either `"major"` or `"minor"`. Ignored when `"off"`. Note that if
#. the scale's limits are updated by other layers or expansions then its
#. breaks are recomputed and might end up different to the value copied for
#. the bin edges. This is not an issue when the scale uses a fixed breaks
#. vector.
#' the scale's limits are updated by other layers or expansions then its
#' breaks are recomputed and might end up different to the value copied for
#' the bin edges. This is not an issue when the scale uses a fixed breaks
#' vector.
#' @param closed One of `"right"` or `"left"` indicating whether right
#' or left edges of bins are included in the bin.
#' @param pad If `TRUE`, adds empty bins at either end of x. This ensures
@@ -64,7 +64,7 @@ stat_bin <- function(mapping = NULL, data = NULL,
breaks = NULL,
closed = c("right", "left"),
pad = FALSE,
follow.scale = c("off", "minor", "major"),
follow.scale = "off",
na.rm = FALSE,
keep.zeroes = "all",
orientation = NA,
@@ -144,15 +144,9 @@ StatBin <- ggproto("StatBin", Stat,
cli::cli_abort("Only one of {.arg boundary} and {.arg center} may be specified in {.fn {snake_class(self)}}.")
}

if (!is.null(params$follow.scale)) {
params$follow.scale <- match.arg(params$follow.scale, c("off", "minor", "major"))
if (params$follow.scale == "off") params$follow.scale <- NULL
}
if (!is.null(params$follow.scale) && !is.null(params$breaks)) {
cli::cli_abort("Only one of {.arg follow.scale} and {.arg breaks} may be specified in {.fn {snake_class(self)}}.")
}
params$follow.scale <- match.arg(params$follow.scale, c("off", "minor", "major"))

if (is.null(params$breaks) && is.null(params$binwidth) && is.null(params$bins) && is.null(params$follow.scale)) {
if (is.null(params$breaks) && is.null(params$binwidth) && is.null(params$bins) && (params$follow.scale == "off")) {
cli::cli_inform("{.fn {snake_class(self)}} using {.code bins = 30}. Pick better value with {.arg binwidth}.")
params$bins <- 30
}
@@ -166,12 +160,12 @@ StatBin <- ggproto("StatBin", Stat,
center = NULL, boundary = NULL,
closed = c("right", "left"), pad = FALSE,
breaks = NULL, flipped_aes = FALSE, keep.zeroes = "all",
follow.scale = NULL,
follow.scale = "off",
# The following arguments are not used, but must
# be listed so parameters are computed correctly
origin = NULL, right = NULL, drop = NULL) {
x <- flipped_names(flipped_aes)$x
if (!is.null(follow.scale)) {
if (follow.scale != "off") {
breaks <- switch(follow.scale,
minor = scales[[x]]$get_breaks_minor(),
major = scales[[x]]$get_breaks())
8 changes: 6 additions & 2 deletions man/geom_histogram.Rd

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


Unchanged files with check annotations Beta

#' # sub-optimal breaks since they are no longer updated after stats
#' p + scale_x_continuous(breaks = breaks_cached(scales::breaks_extended()))
breaks_cached <- function(breaks) {
if (! rlang::is_function(breaks)) {
cli::cli_abort("{.arg breaks} must be a function")

Check warning on line 32 in R/breaks_cached.R

Codecov / codecov/patch

R/breaks_cached.R#L31-L32

Added lines #L31 - L32 were not covered by tests
}
cached <- ggplot2::ggproto(
"BreaksCached", NULL,
fn = breaks,
cached = NULL,
get_breaks = function(self, limits) {
if (is.null(self$cached)) self$cached <- self$fn(limits)
self$cached
}
)$get_breaks

Check warning on line 43 in R/breaks_cached.R

Codecov / codecov/patch

R/breaks_cached.R#L35-L43

Added lines #L35 - L43 were not covered by tests
class(cached) <- c("ggplot2_cached_breaks", class(cached))
cached

Check warning on line 46 in R/breaks_cached.R

Codecov / codecov/patch

R/breaks_cached.R#L45-L46

Added lines #L45 - L46 were not covered by tests
}
#' @export
format.ggplot2_cached_breaks <- function(x, ...) {
bc <- environment(x)$self
inner <- environment(bc$fn)$f

Check warning on line 52 in R/breaks_cached.R

Codecov / codecov/patch

R/breaks_cached.R#L51-L52

Added lines #L51 - L52 were not covered by tests
paste0(
"<cached breaks function>\n",
ifelse(
is.null(bc$cached),
paste0(" ", format(inner), collapse = "\n"),
paste0(" [", class(bc$cached), "] ", paste0(format(bc$cached), collapse = " "))
)
)

Check warning on line 61 in R/breaks_cached.R

Codecov / codecov/patch

R/breaks_cached.R#L54-L61

Added lines #L54 - L61 were not covered by tests
}
#' @export
print.ggplot2_cached_breaks <- function(x, ...) {
cat(format(x), sep = "")

Check warning on line 66 in R/breaks_cached.R

Codecov / codecov/patch

R/breaks_cached.R#L66

Added line #L66 was not covered by tests
}