Skip to content

Instantly share code, notes, and snippets.

@Aariq
Last active October 4, 2024 19:07
Show Gist options
  • Save Aariq/31fadc649813bf87cc6fa7779efa68de to your computer and use it in GitHub Desktop.
Save Aariq/31fadc649813bf87cc6fa7779efa68de to your computer and use it in GitHub Desktop.
A way to ensure limits are included in the breaks on a scale and get labeled with ≤ and ≥ when using oob_squish()
library(ggplot2)
library(scales)
breaks_limits <- function (n = 5, tol = 0.1, min = TRUE, max = TRUE, ...)
{
n_default <- n
scales:::force_all(n, tol, min, max, ...)
function(x, n = n_default) {
breaks <- pretty(x, n, ...)
#force limits to be included and remove breaks outside of limits
if (isTRUE(min)) {
breaks <- c(x[1], breaks)
}
if (isTRUE(max)) {
breaks <- c(x[2], breaks)
}
breaks <- unique(sort(breaks))
breaks <- breaks[breaks>=x[1] & breaks<=x[2]]
#remove breaks too close to limits that they are likely to overlap
scl_br <- (breaks - min(breaks)) / diff(range(breaks)) #or diff(x)
if (isTRUE(min) & abs(scl_br[1] - scl_br[2]) < tol) {
breaks <- breaks[-2]
}
if (isTRUE(max) & abs(scl_br[length(scl_br)] - scl_br[length(scl_br) - 1]) < tol) {
breaks <- breaks[-(length(breaks)-1)]
}
labels <- as.character(breaks)
if (isTRUE(min)) {
labels[1] <- paste0("≤ ", labels[1])
}
if (isTRUE(max)) {
labels[length(labels)] <- paste0("≥ ", labels[length(labels)])
}
names(breaks) <- labels
breaks
}
}
ggplot(faithful, aes(waiting, eruptions, color = eruptions)) +
geom_point() +
scale_y_continuous(
limits = c(NA, 4.2),
breaks = breaks_limits(min = FALSE),
labels = \(x) names(x),
oob = oob_squish,
expand = c(0,0)
) +
scale_color_continuous(
limits = c(NA, 4.2),
breaks = breaks_limits(min = FALSE),
labels = \(x) names(x),
oob = oob_squish
) +
coord_cartesian(clip = "off")
@Aariq
Copy link
Author

Aariq commented Oct 4, 2024

More discussion on this here: r-lib/scales#441

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment