如何用facet_grid()创建Y轴等距且美观的自由刻度断点
facet_grid() with Free Scales Hi Malte, I get it—getting those 3 clean, evenly spaced y-axis breaks per facet can be tricky when using scales = "free_y". Let's tweak your code to fix that!
The Problem with Your Current Function
Your equal_breaks() function adds a margin via the s parameter and rounds to 2 decimal places, which can lead to unappealing, uneven-looking breaks. Instead, we can leverage R's built-in pretty() function to generate "nice" (human-readable) break points while ensuring exactly 3 evenly spaced values per facet.
Improved Break Function
Here's a revised function that prioritizes both uniformity and readability:
nice_3_breaks <- function() { function(x) { # Get initial pretty breaks for the facet's y-range pretty_breaks <- pretty(x, n = 3) # Handle cases where pretty returns more than 3 breaks (pick first, middle, last) if (length(pretty_breaks) > 3) { mid_idx <- floor(length(pretty_breaks) / 2) pretty_breaks <- pretty_breaks[c(1, mid_idx, length(pretty_breaks))] } # Handle edge cases where pretty returns fewer than 3 (force 3 evenly spaced) else if (length(pretty_breaks) < 3) { pretty_breaks <- seq(min(x), max(x), length.out = 3) # Round to 1 decimal place for cleanliness (adjust as needed) pretty_breaks <- round(pretty_breaks, 1) } pretty_breaks } }
Updated Plot Code
Swap out your old breaks function with this new one in your ggplot code:
# Packages library(dplyr) library(ggplot2) library(scales) # Test Data set.seed(123) result_df <- data.frame( variable = rep(c(1,2,3,4), each = 4), mode = rep(c(1,2), each = 2), treat = rep(c(1,2)) %>% as.factor(), mean = rnorm(16, mean = .7, sd = 0.2), x = abs(rnorm(16, mean = 0, sd = 0.5)) ) %>% mutate(lower = mean - x,upper = mean + x) ## Plot with Fixed Breaks result_df %>% ggplot(aes(y = mean*100, x = treat)) + geom_pointrange(aes(ymin = lower*100, ymax = upper*100), shape = 20) + facet_grid(variable ~ mode, scales = "free_y")+ scale_y_continuous(breaks = nice_3_breaks())+ labs(x = "", y = "")
How This Works
- The
pretty()function automatically selects break points that are easy to read (like multiples of 10, 5, etc.) instead of arbitrary decimals. - We adjust for cases where
pretty()returns more or fewer than 3 breaks to ensure exactly 3 evenly spaced values per facet. - The rounding step keeps the breaks clean without sacrificing uniformity.
This should give you the clean, consistent y-axis breaks you're looking for across all your facets!
内容的提问来源于stack exchange,提问作者m_ky

