Different breaks per facet in ggplot2 histogram

前端 未结 4 1640
青春惊慌失措
青春惊慌失措 2020-11-30 07:40

A ggplot2-challenged latticist needs help: What\'s the syntax to request variable per-facet breaks in a histogram?

library(ggplot2)
d = data.frame(x=c(rnorm(         


        
相关标签:
4条回答
  • 2020-11-30 08:17

    I don't think that it is possible to give different break points in each facet.

    As workaround you can make two plots and then with grid.arrange() function from library gridExtra put them together. To set break points in geom_histogram() use binwidth= and set one value for width of bin.

    p1<-ggplot(subset(d,par=="a"), aes(x=x) ) + 
      geom_histogram(binwidth=0.1) +
      facet_wrap(~ par)
    
    p2<-ggplot(subset(d,par=="b"), aes(x=x) ) + 
      geom_histogram(binwidth=0.2) +
      facet_wrap(~ par)
    library(gridExtra)
    grid.arrange(p1,p2,ncol=2)
    

    enter image description here

    0 讨论(0)
  • 2020-11-30 08:22

    Following on from Didzis example:

    ggplot(dat=d, aes(x=x, y=..ncount..)) +
      geom_histogram(data = d[d$par == "a",], binwidth=0.1) +
      geom_histogram(data = d[d$par == "b",], binwidth=0.01) +  
      facet_grid(.~ par, scales="free")
    

    EDIT: This works for more levels but of course there are already better solutions

    # More facets
    d <- data.frame(x=c(rnorm(200,10,0.1),rnorm(200,20,0.1)),par=rep(letters[1:4],each=100))
    
    # vector of binwidths same length as number of facets - need a nicer way to calculate these
    my.width=c(0.5,0.25,0.1,0.01)
    
    out<-lapply(1:length(my.width),function(.i) data.frame(par=levels(d$par)[.i],ggplot2:::bin(d$x[d$par==levels(d$par)[.i]],binwidth=my.width[.i])))
    
    my.df<-do.call(rbind , out)
    
    ggplot(my.df) + geom_histogram(aes(x, y = density, width = width), stat =  "identity") + facet_wrap(~par,scales="free")
    

    from https://groups.google.com/forum/?fromgroups=#!searchin/ggplot2/bin$20histogram$20by$20facet/ggplot2/xlqRIFPP-zE/CgfigIkgAAkJ

    0 讨论(0)
  • 2020-11-30 08:30

    It is not, strictly speaking, possible to give different breaks in the different facets. But you can get the same effect by having a different layer for each facet (much as in user20650's answer), but mostly automating the multiple geom_histogram calls:

    d <- data.frame(x=c(rnorm(100,10,0.1),rnorm(100,20,0.1)),
                    par=rep(letters[1:2],each=100))
    breaks <- list(a=seq(9,11,by=0.1),b=seq(19,21,by=0.2))
    
    ggplot(d, aes(x=x)) +
      mapply(function(d, b) {geom_histogram(data=d, breaks=b)}, 
             split(d, d$par), breaks) +
      facet_wrap(~ par,  scales="free_x")
    

    enter image description here

    The mapply call creates a list of geom_histograms which can be added to the plot. The tricky part is that you have to manually split the data (split(d, d$par)) into the data that goes into each facet.

    0 讨论(0)
  • 2020-11-30 08:36

    Here is one alternative:

    hls <- mapply(function(x, b) geom_histogram(data = x, breaks = b), 
                  dlply(d, .(par)), myBreaks)
    ggplot(d, aes(x=x)) + hls + facet_wrap(~par, scales = "free_x")
    

    enter image description here

    If you need to shrink the range of x, then

    hls <- mapply(function(x, b) {
      rng <- range(x$x)
      bb <- c(rng[1], b[rng[1] <= b & b <= rng[2]], rng[2])
      geom_histogram(data = x, breaks = bb, colour = "white")
    }, dlply(d, .(par)), myBreaks)
    
    ggplot(d, aes(x=x)) + hls + facet_wrap(~par, scales = "free_x")
    

    enter image description here

    0 讨论(0)
提交回复
热议问题