ggplot Integer Breaks on Facets

不羁岁月 提交于 2020-06-16 02:12:09

问题


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:

  1. There is an integer lower break at or below the lowest value value for each facet.
  2. 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!