-
Notifications
You must be signed in to change notification settings - Fork 108
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
Feature request: transform_squish
or label_squish
#441
Comments
Hmm.. this seems fairly impossible to do in a way that fits in with how other |
While not identical, #368 also had a similar goal in mind. |
Yeah, that's part of the way there, but there's no guarantee that the limits are included in the labels. The examples in #368 just happen to work because of the chosen limits. For example: library(ggplot2)
library(scales)
ggplot(faithful, aes(waiting, eruptions)) +
geom_point() +
scale_y_continuous(
limits = c(2, 4.2),
labels = \(...) {l <- scales::label_number()(...); l[c(1, length(l))] <- paste0(c("≤","≥"), l[c(1, length(l))]); l},
oob = oob_squish
) #no label for ≥4.2 Created on 2024-10-04 with reprex v2.1.1 It'd be nice to be able to enforce that the limits appear as labels in a way that looks nice-ish (not overlapping with other labels), but maybe this is a separate issue. |
This is as far as I got, but it doesn't quite work for position scales because "Note that for position scales, limits are provided after scale expansion." (from the 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") Created on 2024-10-04 with reprex v2.1.1 |
When passing
scales::squish()
to theoob
argument of a scale (sayscale_fill_viridis_c()
) I find that it would often be nice to also transform the breaks and labels as follows:I'm finding this difficult to do programmatically without setting the breaks and limits manually since the breaks function operates on the values before the squish happens (I think). It would be cool if there were labeling and breaks functions that could help automate this.
Created on 2024-07-01 with reprex v2.1.0
Session info
The text was updated successfully, but these errors were encountered: