问题
library(tidyverse)
df <- tibble(col1 = rep(c("A", "B"), 2),
col2 = c(0.4, 0.7, 3, 9),
col3 = c("I", "I", "II", "II"))
#> # A tibble: 4 x 3
#> col1 col2 col3
#> <chr> <dbl> <chr>
#> 1 A 0.4 I
#> 2 B 0.7 I
#> 3 A 3 II
#> 4 B 9 II
ggplot(df, aes(col1, col2)) +
geom_col() +
facet_wrap(vars(col3), scales = "free")
I want to create integer breaks for the ggplot above such that:
- There is an integer lower break at or below the lowest value value for each facet.
- There is an integer upper break at or above the highest value value for each facet.
For my first facet I
the integer values for the axis would include 0
and 1
. For the second facet II
the integer values should include at the min 0
and the max integer would have to be at least 9
, maybe 10
would look better, depending on the routine used for creating the breaks.
These attempts from this older stackoverflow question don't quite work.
# Attempt 1
ggplot(df, aes(col1, col2)) +
geom_col() +
facet_wrap(vars(col3), scales = "free") +
scale_y_continuous(
breaks = function(x) unique(floor(pretty(seq(0, (max(x) + 1) * 1.1)))))
# Attempt 2
ggplot(df, aes(col1, col2)) +
geom_col() +
facet_wrap(vars(col3), scales = "free") +
scale_y_continuous(breaks = scales::pretty_breaks(2))
# Attempt 3
ggplot(df, aes(col1, col2)) +
geom_col() +
facet_wrap(vars(col3), scales = "free") +
scale_y_continuous(breaks = c(0, 1))
# Attempt 4
ggplot(df, aes(col1, col2)) +
geom_col() +
facet_wrap(vars(col3), scales = "free") +
scale_y_continuous(
breaks = function(x) seq(ceiling(x[1]), floor(x[2]), by = 1))
# Attempt 5
ggplot(df, aes(col1, col2)) +
geom_col() +
facet_wrap(vars(col3), scales = "free") +
scale_y_continuous(
breaks =
function(x, n = 5) pretty(x, n)[round(pretty(x, n),1) %% 1 == 0])
Most attempts produce something like the following. Notice the missing 1
break on the first facet. And I'd want the second facet to have a break at 10
. I don't want to manually set limits or breaks because in reality I have hundreds of facets. Hopefully one of the functions above can be modified to fit my requirements.
回答1:
To achieve the desired result you also have to adjust the limits of the y-axis. Try this:
library(tidyverse)
df <- tibble(col1 = rep(c("A", "B"), 2),
col2 = c(0.4, 0.7, 3, 9),
col3 = c("I", "I", "II", "II"))
my_ceil <- function(x) {
ceil <- ceiling(max(x))
ifelse(ceil > 1 & ceil %% 2 == 1, ceil + 1, ceil)
}
my_breaks <- function(x) {
ceil <- my_ceil(max(x))
unique(ceiling(pretty(seq(0, ceil))))
}
my_limits <- function(x) {
ceil <- my_ceil(x[2])
c(x[1], ceil)
}
ggplot(df, aes(col1, col2)) +
geom_col() +
facet_wrap(vars(col3), scales = "free") +
scale_y_continuous(breaks = my_breaks, limits = my_limits)
Created on 2020-05-21 by the reprex package (v0.3.0)
来源:https://stackoverflow.com/questions/61915427/ggplot-integer-breaks-on-facets