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:
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.
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)