Search code examples
rggplot2histogram

Set binwidth to a factor of the x variable range in ggplot geom_histogram


I'd like to create histograms of multiple variables, but for each facet I want the binwidth to be the size of the range between min and max for the x variable, divided by 20.

Using iris as an example this is what I have tried

irislong= pivot_longer(iris, cols = -Species)

ggplot(irislong, aes(x= value))+
  geom_histogram(binwidth = (max("value")- min("value"))/20, colour= "black") # also tried without "" around value
  facet_wrap(~ name, scales = "free")

Solution

  • You could pre-calculate each binwidth per group and add them in the binwidth aesthetics like this:

    library(tidyr)
    irislong= pivot_longer(iris, cols = -Species)
    
    library(ggplot2)
    library(dplyr)
    p <- irislong %>%
      group_by(name) %>%
      mutate(width = (max(value) - min(value))/20) %>%
      ungroup() %>%
      ggplot(aes(x = value, binwidth = width, group = name)) +
      geom_histogram(colour = 'black') +
      facet_wrap(~name, scales = 'free')
    
    p
    

    # Check binwidths in layer
    q <- ggplot_build(p)
    
    q$data[[1]] %>%
      group_by(group) %>%
      summarise(binwidth = unique(binwidth))
    #> # A tibble: 4 × 2
    #>   group binwidth
    #>   <int>    <dbl>
    #> 1     1    0.295
    #> 2     2    0.12 
    #> 3     3    0.18 
    #> 4     4    0.12
    

    Created on 2022-11-23 with reprex v2.0.2