【问题标题】:Different breaks per facet in ggplot2 histogramggplot2直方图中每个方面的不同中断
【发布时间】:2013-06-20 18:04:05
【问题描述】:

受 ggplot2 挑战的 latticist 需要帮助:在直方图中请求变量 per-facet 中断的语法是什么?

library(ggplot2)
d = data.frame(x=c(rnorm(100,10,0.1),rnorm(100,20,0.1)),par=rep(letters[1:2],each=100))
# Note: breaks have different length by par
breaks = list(a=seq(9,11,by=0.1),b=seq(19,21,by=0.2))
ggplot(d, aes(x=x) ) + 
  geom_histogram() + ### Here the ~breaks should be added
  facet_wrap(~ par,  scales="free")

正如jucor、here 所指出的,还有一些解决方案。

应特殊要求,并说明为什么我不是 ggplot 的忠实粉丝,lattice 版本

library(lattice)
d = data.frame(x=c(rnorm(100,10,0.1),rnorm(100,20,0.1)),par=rep(letters[1:2],each=100))
# Note: breaks have different length by par
myBreaks = list(a=seq(8,12,by=0.1),b=seq(18,22,by=0.2))
histogram(~x|par,data=d,
          panel = function(x,breaks,...){
            # I don't know of a generic way to get the 
            # grouping variable with histogram, so 
            # this is not very generic
            par = levels(d$par)[which.packet()]
            breaks = myBreaks[[par]]
            panel.histogram(x,breaks=breaks,...)
          },
          breaks=NULL, # important to force per-panel compute
          scales=list(x=list(relation="free")))

【问题讨论】:

  • 作为一名格子后卫..你能分享格子版本吗..
  • 您可以在 ggplot2 之外进行分箱,例如将hist 与ddply 或data.table 或...结合使用,并制作条形图。
  • 是的,这看起来像是要走的方法。由于这是另一位作者的包裹,因此需要一些工作。 github.com/xfim/ggmcmc/pull/17

标签: r ggplot2 histogram


【解决方案1】:

我认为不可能在每个方面给出不同的断点。

作为解决方法,您可以制作两个图,然后使用库 gridExtra 中的 grid.arrange() 函数将它们放在一起。要在 geom_histogram() 中设置断点,请使用 binwidth= 并为 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)

【讨论】:

  • 谢谢,如果没有其他选择(我担心),我稍后会接受。然而,对于真正的工作,我有数百个贝叶斯图的直方图,所以它变得混乱:见github.com/xfim/ggmcmc/pull/17。
【解决方案2】:

这是另一种选择:

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")

如果需要缩小x的范围,那么

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")

【讨论】:

  • 大师再次出击。尽管如此:晶格解决方案即使不完美,也更加透明。
  • 不错的方法。谢谢。不幸的是,应用不同的 binwidth 作为密度曲线的比例因子并没有帮助... geom_density(data = x, aes(y = binwidth * ..count..))
  • 你能解释一下第一个mapply里面发生了什么吗?
【解决方案3】:

以 Didzis 为例:

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")

编辑:这适用于更多级别,但当然已经有更好的解决方案

# 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")

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

【讨论】:

  • 这适用于示例,但不容易推广到贝叶斯估计的 100 多个案例。
【解决方案4】:

严格来说,不可能在不同的方面给出不同的中断。但是您可以通过为每个方面设置不同的层来获得相同的效果(就像在user20650's answer 中一样),但主要是自动化多个geom_histogram 调用:

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")

mapply 调用创建了一个 geom_histograms 列表,可以将其添加到绘图中。棘手的部分是您必须手动将数据 (split(d, d$par)) 拆分为进入每个方面的数据。

【讨论】:

    猜你喜欢
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多