ggplot2直方图中每个面的不同间断

21

一位不熟悉ggplot2的lattice图形用户需要帮助:如何请求在直方图中每个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所指出的,这里提供了更多解决方案。

应特殊要求,并展示我为何不是一个伟大的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")))

enter image description here


1
作为一个格子防御者,你能分享一下格子版本吗? - agstudy
1
你可以在ggplot2之外进行分箱,例如使用 hist 结合 ddplydata.table 等方式,并制作条形图。 - Roland
是的,那看起来就是正确的方法。由于这是另一位作者的软件包,需要进行一些工作。https://github.com/xfim/ggmcmc/pull/17 - Dieter Menne
4个回答

17

这里有一个替代方案:

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

输入图片说明


大师再次发威。尽管如此:如果不是完美的话,格子解决方案更加透明。 - Dieter Menne
不错的方法。谢谢。不幸的是,它不能将不同的binwidth应用为密度曲线的缩放因子...... geom_density(data = x, aes(y = binwidth * ..count..)) - Antje Janosch
你能解释一下第一个 mapply 内部发生了什么吗? - randy

5

我认为在每个方面中都设置不同的断点是不可能的。

作为解决方法,您可以创建两个图表,然后使用gridExtra库中的grid.arrange()函数将它们组合在一起。要在geom_histogram()中设置断点,请使用binwidth=并设置一个值作为条形柱的宽度。

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


谢谢,如果没有其他选择的话(我很担心),我会稍后接受它。然而,对于真正的工作,我有一些贝叶斯图的直方图,所以会变得杂乱无章:请参见https://github.com/xfim/ggmcmc/pull/17. - Dieter Menne

4

继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的帖子,介绍了如何使用ggplot2制作分面直方图。


这对于例子是有效的,但对于从贝叶斯估计得出的100多个情况并不容易泛化。 - Dieter Menne

3

严格来说,在不同的面上无法进行不同的断点。但您可以通过为每个面创建一个不同的图层(类似于user20650的答案)来达到相同的效果,但通常是自动化多个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")

enter image description here

mapply调用会创建一个geom_histogram列表,可以将其添加到图形中。棘手的部分是您必须手动将数据(split(d, d$par))拆分为每个面板所需的数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接