绘制“密度”对象时出现问题

Issue with when plotting `density` objects

我在尝试绘制 density 对象时遇到问题。考虑例如

require(grDevices)

set.seed(43)
d0 = density(rexp(1e5,rate=1))
d1 = density(rexp(1e5,rate=1.8))


plot(d1, col="white", xlab = "x", ylab="Density", main = "")
polygon(d1, col=adjustcolor("blue", alpha.f=0.2))
lines(d0, col="white")
polygon(d0, col=adjustcolor("red", alpha.f=0.2))

目前,它看起来符合我的预期。缩放 Y 轴的低值时会出现问题。考虑例如

plot(d1, col="white", xlim=c(2.5,3), xlab = "x", ylab="Density", main = "", 
ylim=c(0,0.02))
polygon(d1, col=adjustcolor("blue", alpha.f=0.2))
lines(d0, col="white", xlim=c(2.5,3), ylim=c(0,0.02))
polygon(d0, col=adjustcolor("red", alpha.f=0.2))

奇怪的是,多边形的下部没有达到密度 = 0。而且,一个多边形的末端低于另一个。设置 yaxs="i"xaxs="i" 时问题仍然存在。

这是怎么回事,如何解决这个问题?


有了一些个人数据,我得到了

你能通过将两端的 y 值都固定为零来作弊吗?

set.seed(43)
d0 = density(rexp(150,rate=1))
d1 = density(rexp(150,rate=1.8))

d0$y[c(1, length(d0$y))] <- 0
d1$y[c(1, length(d1$y))] <- 0

plot(d1, col="white", xlim=c(2.5,3), xlab = "x", ylab="Density", main = "", 
ylim=c(0,0.02))
polygon(d1, col=adjustcolor("blue", alpha.f=0.2))
lines(d0, col="white", xlim=c(2.5,3), ylim=c(0,0.02))
polygon(d0, col=adjustcolor("red", alpha.f=0.2))

稍微改进一下就是降低整个多边形,使其中一端接触基线,然后将下一个设置为零:

set.seed(43)
d0 = density(rexp(150,rate=1))
d1 = density(rexp(150,rate=1.8))

ends0 <- d0$y[c(1, length(d0$y))]
ends1 <- d1$y[c(1, length(d1$y))]

d0$y <- d0$y - min(ends0)
d1$y <- d1$y - min(ends1)

d0$y[c(1, length(d0$y))] <- 0
d1$y[c(1, length(d1$y))] <- 0


plot(d1, col="white", xlim=c(2.5,3), xlab = "x", ylab="Density", main = "", 
ylim=c(0,0.02))
polygon(d1, col=adjustcolor("blue", alpha.f=0.2))
lines(d0, col="white", xlim=c(2.5,3), ylim=c(0,0.02))
polygon(d0, col=adjustcolor("red", alpha.f=0.2))

这是一个没有校正的,用于比较。

另一种选择是将密度估计的 x 范围扩展到数据范围之外一点,以便密度估计在两端实际上都为零。这避免了人为更改密度估计中的任何值的需要。例如:

set.seed(43)
d0 = density(rexp(1e5,rate=1))
d1 = density(rexp(1e5,rate=1.8))

d1$y[c(1, length(d1$y))]

[1] 2.987316e-03 1.235864e-06

set.seed(43)
d1 = rexp(1e5,rate=1.8)
d1 = density(d1, from=min(d1) - 0.05*diff(range(d1)), to=max(d1) + 0.05*diff(range(d1)))

d1$y[c(1, length(d1$y))]

[1] 6.334144e-17 3.797333e-17