提问人:Sacha Epskamp 提问时间:4/17/2011 最后编辑:B--rianSacha Epskamp 更新时间:9/23/2022 访问量:71725
带有密度曲线的叠加直方图
Overlay histogram with density curve
问:
我正在尝试制作密度值的直方图,并将其与密度函数的曲线(不是密度估计)叠加。
使用一个简单的标准正态示例,以下是一些数据:
x <- rnorm(1000)
我可以做:
q <- qplot( x, geom="histogram")
q + stat_function( fun = dnorm )
但这给出了直方图的频率比例,而不是密度。我可以在直方图上获得适当的刻度:..density..
q <- qplot( x,..density.., geom="histogram")
q
但现在这给出了一个错误:
q + stat_function( fun = dnorm )
有什么我没有看到的吗?
另一个问题,有没有办法绘制函数的曲线,比如 ,但不是层?curve()
答:
60赞
Ramnath
4/17/2011
#1
给你!
# create some data to work with
x = rnorm(1000);
# overlay histogram, empirical density and normal density
p0 = qplot(x, geom = 'blank') +
geom_line(aes(y = ..density.., colour = 'Empirical'), stat = 'density') +
stat_function(fun = dnorm, aes(colour = 'Normal')) +
geom_histogram(aes(y = ..density..), alpha = 0.4) +
scale_colour_manual(name = 'Density', values = c('red', 'blue')) +
theme(legend.position = c(0.85, 0.85))
print(p0)
评论
8赞
Maxim.K
11/25/2013
P.S. 如果使用真实数据,请确保将经验平均值和 sd 参数传递给 dnorm 函数,请参阅语法stat_function帮助。
1赞
Jemus42
2/13/2014
只是出于好奇:如何使用 ggplot() 函数完成此操作?我只是勉强理解 ggplot() 的工作方式,所以我觉得用这种方法来做我的东西有点奇怪。
2赞
nzcoops
5/12/2014
@Jemus42你可以把第一行换成这样的内容 “ggplot(data.frame(x), aes(x=x)) +”
0赞
Shaun Jackman
1/30/2015
@Jemus42 这是为什么呢?如果不在 args 中传递 mean 和 sd 来stat_function我什么也得不到。
2赞
sunny
6/26/2015
叠加直方图和密度估计存在一个问题,即密度估计实际上应该移动半个二进制宽度,以实现最准确和美观的演示。我一直无法弄清楚如何做到这一点。有接受者吗?
46赞
Axeman
12/16/2015
#2
Ramnath 答案的更基本的替代方案,传递观察到的平均值和标准差,并使用 :ggplot
qplot
df <- data.frame(x = rnorm(1000, 2, 2))
# overlay histogram and normal density
ggplot(df, aes(x)) +
geom_histogram(aes(y = after_stat(density))) +
stat_function(
fun = dnorm,
args = list(mean = mean(df$x), sd = sd(df$x)),
lwd = 2,
col = 'red'
)
评论
2赞
elcortegano
4/20/2018
这是一个非常方便的答案,因为它提供了一种绘制直方图和密度曲线的方法,即使它们属于不同的分布,如果需要(就像我一样)。谢谢!
0赞
Megatron
8/25/2021
最初的问题是关于拟合密度曲线,而不是专门拟合单个高斯曲线。如果要查看此解决方案不起作用的原因,请尝试将数据设置为df <- data.frame(x = c(rnorm(1000, 2, 2), rnorm(1000, 12, 2)))
0赞
Axeman
10/8/2021
@Megatron,不,OP要求“密度函数的曲线(不是密度估计)”。所以我仍然认为这是正确的。您的示例表明,在某些情况下,正态密度函数可能不是对数据的良好描述,但这不是重点。
18赞
user29609
2/15/2019
#3
使用从呢?这样:geom_density()
ggplot2
df <- data.frame(x = rnorm(1000, 2, 2))
ggplot(df, aes(x)) +
geom_histogram(aes(y=..density..)) + # scale histogram y
geom_density(col = "red")
这也适用于多模式分布,例如:
df <- data.frame(x = c(rnorm(1000, 2, 2), rnorm(1000, 12, 2), rnorm(500, -8, 2)))
ggplot(df, aes(x)) +
geom_histogram(aes(y=..density..)) + # scale histogram y
geom_density(col = "red")
评论
1赞
Axeman
7/18/2019
因为 OP 要求“密度函数的曲线(不是密度估计)”。 给出密度估计值。geom_density
6赞
David C
1/17/2020
也许不是OP所要求的,但这确实对我正在寻找的东西有所帮助!
2赞
Ben
3/16/2022
@Axeman 密度函数和密度估计有什么区别?
0赞
Bikash Pokharel
9/23/2022
#4
我正在尝试虹膜数据集。您应该能够在这些简单代码中看到所需的图形:
ker_graph <- ggplot(iris, aes(x = Sepal.Length)) +
geom_histogram(aes(y = ..density..),
colour = 1, fill = "white") +
geom_density(lwd = 1.2,
linetype = 2,
colour = 2)
评论
qplot
stat_function
qplot(x, geom = 'blank') + geom_histogram(aes(y = ..density..)) + stat_function(fun = dnorm)
curve(dnorm, -4, 4)
qplot(x = -4:4, stat = 'function', fun = dnorm, geom = 'line')