R中的ggplot2覆盖直方图


124

我是R的新手,正在尝试将3个直方图绘制到同一张图上。一切工作正常,但是我的问题是您看不到2个直方图重叠的地方-它们看起来很截断。

当我进行密度图绘制时,它看起来很完美:每条曲线都被黑色边框包围,在曲线重叠的地方颜色看起来不同。

有人可以告诉我第一张图片中的直方图是否可以实现类似的效果吗?这是我正在使用的代码:

lowf0 <-read.csv (....)
mediumf0 <-read.csv (....)
highf0 <-read.csv(....)
lowf0$utt<-'low f0'
mediumf0$utt<-'medium f0'
highf0$utt<-'high f0'
histogram<-rbind(lowf0,mediumf0,highf0)
ggplot(histogram, aes(f0, fill = utt)) + geom_histogram(alpha = 0.2)

3
直方图和密度图的超链接已损坏
Daghan ---

Answers:


115

您当前的代码:

ggplot(histogram, aes(f0, fill = utt)) + geom_histogram(alpha = 0.2)

我告诉ggplot大家使用中的所有值来构造一个直方图f0,然后根据变量给该单个直方图的条形上色utt

相反,您想要的是创建三个单独的直方图,并进行alpha混合,以便彼此可见。因此,您可能想对分别使用三个调用geom_histogram,每个调用都获得自己的数据框并填充:

ggplot(histogram, aes(f0)) + 
    geom_histogram(data = lowf0, fill = "red", alpha = 0.2) + 
    geom_histogram(data = mediumf0, fill = "blue", alpha = 0.2) +
    geom_histogram(data = highf0, fill = "green", alpha = 0.2) +

这是一个带有一些输出的具体示例:

dat <- data.frame(xx = c(runif(100,20,50),runif(100,40,80),runif(100,0,30)),yy = rep(letters[1:3],each = 100))

ggplot(dat,aes(x=xx)) + 
    geom_histogram(data=subset(dat,yy == 'a'),fill = "red", alpha = 0.2) +
    geom_histogram(data=subset(dat,yy == 'b'),fill = "blue", alpha = 0.2) +
    geom_histogram(data=subset(dat,yy == 'c'),fill = "green", alpha = 0.2)

产生这样的事情:

在此处输入图片说明

编辑以纠正错别字;您想要填充而不是颜色。


7
当子集的大小不同时,这将不起作用。知道如何解决吗?(例如,使用“ a”上为100点,“ b”上为50点的数据)。
豪尔赫·雷涛

3
这种方法的一个缺点是我很难让它显示图例(尽管这可能是由于我缺乏知识)。@kohske在下面的其他答案将默认显示图例,然后可以使用修改图例(以及直方图上显示的特定颜色)scale_fill_manual()
Michael Ohlrogge'9

1
确切地说,我们如何在其中添加图例?
shenglih

1
@shenglih传说中,kohske的回答更好。他的回答总体上也更好。
joran

f0来自哪里?
艾伦

256

使用@joran的样本数据,

ggplot(dat, aes(x=xx, fill=yy)) + geom_histogram(alpha=0.2, position="identity")

请注意,默认位置geom_histogram是“堆栈”。

请参阅此页面的“位置调整”:

docs.ggplot2.org/current/geom_histogram.html


30
我认为这应该是最好的答案,因为它避免了重复代码
kfor

6
position = 'identity'不仅是一个更具可读性的答案,它还可以与更复杂的图更好地融合在一起,例如对aes()和的混合调用aes_string()
rensa '16

2
该答案还将自动显示颜色的图例,而@joran的答案则不会。然后可以使用例如修改图例scale_fill_manual()。此功能还可用于修改直方图中的颜色。
Michael Ohlrogge'9

4
另外,请确保in fill中使用的变量是一个因素。
hhh

9
我个人认为stackoverflow应该首先列出最受好评的答案。“正确答案”仅代表一个人的意见。
daknowles

25

尽管仅需几行即可在ggplot2中绘制多个/重叠的直方图,但结果并不总是令人满意。需要适当使用边框和颜色以确保眼睛可以区分直方图

以下功能平衡了边框的颜色,不透明度和叠加的密度图,使观看者可以区分各种分布

单个直方图

plot_histogram <- function(df, feature) {
    plt <- ggplot(df, aes(x=eval(parse(text=feature)))) +
    geom_histogram(aes(y = ..density..), alpha=0.7, fill="#33AADE", color="black") +
    geom_density(alpha=0.3, fill="red") +
    geom_vline(aes(xintercept=mean(eval(parse(text=feature)))), color="black", linetype="dashed", size=1) +
    labs(x=feature, y = "Density")
    print(plt)
}

多个直方图

plot_multi_histogram <- function(df, feature, label_column) {
    plt <- ggplot(df, aes(x=eval(parse(text=feature)), fill=eval(parse(text=label_column)))) +
    geom_histogram(alpha=0.7, position="identity", aes(y = ..density..), color="black") +
    geom_density(alpha=0.7) +
    geom_vline(aes(xintercept=mean(eval(parse(text=feature)))), color="black", linetype="dashed", size=1) +
    labs(x=feature, y = "Density")
    plt + guides(fill=guide_legend(title=label_column))
}

用法

只需将数据框以及所需的参数传递给上述函数即可

plot_histogram(iris, 'Sepal.Width')

在此处输入图片说明

plot_multi_histogram(iris, 'Sepal.Width', 'Species')

在此处输入图片说明

plot_multi_histogram中的额外参数是包含类别标签的列的名称。

通过创建具有许多不同分布方式的数据框,我们可以更加生动地看到这一点:

a <-data.frame(n=rnorm(1000, mean = 1), category=rep('A', 1000))
b <-data.frame(n=rnorm(1000, mean = 2), category=rep('B', 1000))
c <-data.frame(n=rnorm(1000, mean = 3), category=rep('C', 1000))
d <-data.frame(n=rnorm(1000, mean = 4), category=rep('D', 1000))
e <-data.frame(n=rnorm(1000, mean = 5), category=rep('E', 1000))
f <-data.frame(n=rnorm(1000, mean = 6), category=rep('F', 1000))
many_distros <- do.call('rbind', list(a,b,c,d,e,f))

像以前一样传递数据框(并使用选项扩展图表):

options(repr.plot.width = 20, repr.plot.height = 8)
plot_multi_histogram(many_distros, 'n', 'category')

在此处输入图片说明


1
这非常有用,希望引起更多关注。
爱德华·泰勒

2
@EdwardTyler非常正确。我希望我可以不止一次投票!
ayePete
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.