如何使密度图正确显示接近极限的面积?

时间:2019-03-24 23:08:47

标签: r ggplot2 kernel-density

当我用ggplot绘制密度时,似乎在极限范围内是非常错误的。我看到geom_density和其他函数允许指定各种密度内核,但是似乎没有一个可以解决该问题。

如何使用ggplot正确绘制极限附近的密度?


例如,让我们绘制具有2个自由度的卡方分布。使用内置的概率密度:

library(ggplot2)

u = seq(0, 2, by=0.01)
v = dchisq(u, df=2)

df = data.frame(x=u, p=v)

p = ggplot(df) +
    geom_line(aes(x=x, y=p), size=1) +
    theme_classic() +
    coord_cartesian(xlim=c(0, 2), ylim=c(0, 0.5))

show(p)

我们得到了预期的情节:

enter image description here

现在让我们尝试对其进行仿真并绘制经验分布:

library(ggplot2)

u = rchisq(10000, df=2)

df = data.frame(x=u)

p = ggplot(df) +
    geom_density(aes(x=x)) +
    theme_classic() +
    coord_cartesian(xlim=c(0, 2))

show(p)

我们得到了一个错误的情节:

enter image description here

我们可以尝试可视化实际分布:

library(ggplot2, dplyr, tidyr)

u = rchisq(10000, df=2)

df = data.frame(x=u)

p = ggplot(df) +
    geom_point(aes(x=x, y=0.5), position=position_jitter(height=0.2), shape='.', alpha=1) +
    theme_classic() +
    coord_cartesian(xlim=c(0, 2), ylim=c(0, 1))

show(p)

看起来似乎正确,与密度图相反:

enter image description here

问题似乎与内核有关,geom_density确实允许使用不同的内核。但是他们并没有真正纠正极限问题。例如,上面带有triangular的代码看起来大致相同:

enter image description here

这是我期望看到的东西的一个想法(当然,我想要一个密度,而不是直方图):

library(ggplot2)

u = rchisq(10000, df=2)

df = data.frame(x=u)

p = ggplot(df) +
    geom_histogram(aes(x=x), center=0.1, binwidth=0.2, fill='white', color='black') +
    theme_classic() +
    coord_cartesian(xlim=c(0, 2))

show(p)

enter image description here

1 个答案:

答案 0 :(得分:1)

当存在约束时(例如在这种情况下,对于仅支持大于零的密度),通常的内核密度方法会遇到麻烦。通常的建议是使用logspline软件包:

install.packages("logspline")
library(logspline)
png(); fit <- logspline(rchisq(10000, 3))       
plot(fit) ; dev.off()

enter image description here

如果需要在ggplot2环境中完成此操作,则有一个dlogspline函数:

densdf <- data.frame( y=dlogspline(seq(0,12,length=1000), fit), 
                      x=seq(0,12,length=1000))

ggplot(densdf, aes(y=y,x=x))+geom_line()

也许您坚持要拥有2个自由度?

enter image description here