在 R 中用 ggplot2覆盖直方图

我是 R 的新手,正在尝试将3个直方图绘制到同一个图表上。 一切工作正常,但我的问题是,你看不到两个直方图重叠的地方-他们看起来相当截断。

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

谁能告诉我第一幅图中的直方图是否也能达到类似的效果?这是我正在使用的代码:

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)
204097 次浏览

你现在的代码是:

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)

产生了这样的东西:

enter image description here

为了修复打字错误而编辑; 你想要的是填充,而不是颜色。

使用@joran 的示例数据,

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

请注意,geom_histogram的默认位置是“ stack”

请参阅本页的「位置调整」 :

geom_histogram文档

虽然在 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')

enter image description here

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

enter image description here

Plot _ multi _ 柱状图中的 额外参数是包含类别标签的列的名称。

通过使用 许多不同的分配方式创建一个数据框架,我们可以更戏剧性地看到这一点:

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

enter image description here

添加 每个分布的单独垂直线:

plot_multi_histogram <- function(df, feature, label_column, means) {
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(xintercept=means, color="black", linetype="dashed", size=1)
labs(x=feature, y = "Density")
plt + guides(fill=guide_legend(title=label_column))
}

与前面的 图 _ 多直方图函数相比,唯一的变化是在参数中添加了 means,并更改了 geom_vline行以接受多个值。

用法 :

options(repr.plot.width = 20, repr.plot.height = 8)
plot_multi_histogram(many_distros, "n", 'category', c(1, 2, 3, 4, 5, 6))

结果 :

enter image description here

因为我在 many_distros中明确地设置了这些方法,所以我可以简单地传递它们。或者,您可以简单地在函数内部计算这些,并以这种方式使用它们。