我必须承认,我接受了这个挑战是因为我正在寻找展示其他数据集的不同方法。以往我通常会做一些类似于其他答案中所示的scatterhist
2D图表,但我想尝试一下rgl
。
我使用你的函数生成数据。
gibbs<-function (n, rho) {
mat <- matrix(ncol = 2, nrow = n)
x <- 0
y <- 0
mat[1, ] <- c(x, y)
for (i in 2:n) {
x <- rnorm(1, rho * y, (1 - rho^2))
y <- rnorm(1, rho * x, (1 - rho^2))
mat[i, ] <- c(x, y)
}
mat
}
bvn <- gibbs(10000, 0.98)
设置
我使用rgl
进行繁重的工作,但我不知道如何在不使用car
的情况下获得置信椭圆。我猜想还有其他方法可以解决这个问题。
library(rgl)
library(car)
处理数据
获取直方图数据但不绘图,然后提取密度并将其标准化为概率。 *max
变量是为了简化未来的绘图。
hx <- hist(bvn[,2], plot=FALSE)
hxs <- hx$density / sum(hx$density)
hy <- hist(bvn[,1], plot=FALSE)
hys <- hy$density / sum(hy$density)
xmax <- tail(hx$breaks, n=1) + diff(tail(hx$breaks, n=2))
ymax <- tail(hy$breaks, n=1) + diff(tail(hy$breaks, n=2))
zmax <- max(hxs, hys)
在底部绘制基本散点图
根据分布情况设置合适的比例尺。诚然,X轴和Y轴标签的位置不够美观,但这应该很容易根据数据重新定位。
plot3d(bvn[,2], bvn[,1], 0, zlim=c(0, zmax), pch='.',
xlab='X', ylab='Y', zlab='', axes=FALSE)
par3d(scale=c(1,1,3))
后墙上的直方图
我不知道如何让它们在整体 3D 渲染平面上自动绘制,所以我不得不手动制作每个矩形。
for (ii in seq_along(hx$counts)) {
quads3d(hx$breaks[ii]*c(.9,.9,.1,.1) + hx$breaks[ii+1]*c(.1,.1,.9,.9),
rep(ymax, 4),
hxs[ii]*c(0,1,1,0), color='gray80')
}
for (ii in seq_along(hy$counts)) {
quads3d(rep(xmax, 4),
hy$breaks[ii]*c(.9,.9,.1,.1) + hy$breaks[ii+1]*c(.1,.1,.9,.9),
hys[ii]*c(0,1,1,0), color='gray80')
}
概述
bb <- par3d('bbox')
inset <- 0.02
x1 <- bb[1] + (1-inset)*diff(bb[1:2])
y1 <- bb[3] + (1-inset)*diff(bb[3:4])
z1 <- bb[5] + inset*diff(bb[5:6])
dev.new()
de <- dataEllipse(bvn[,1], bvn[,2], draw=FALSE, levels=0.95)
dev.off()
lines3d(de[,2], de[,1], z1, color='green', lwd=3)
denx <- density(bvn[,2])
lines3d(denx$x, rep(y1, length(denx$x)), denx$y / sum(hx$density), col='red', lwd=3)
deny <- density(bvn[,1])
lines3d(rep(x1, length(deny$x)), deny$x, deny$y / sum(hy$density), col='blue', lwd=3)
美化
grid3d(c('x+', 'y+', 'z-'), n=10)
box3d()
axes3d(edges=c('x-', 'y-', 'z+'))
outset <- 1.2
mtext3d('P(X)', edge='x+', pos=c(0, ymax, outset * zmax))
mtext3d('P(Y)', edge='y+', pos=c(xmax, 0, outset * zmax))
最终产品
使用rgl
的一个优点是可以用鼠标将其旋转并找到最佳视角。虽然没有为此SO页面制作动画,但完成上述所有操作应该允许您拥有足够的播放时间。(如果旋转它,您将能够看到线条略微在直方图前面,并且略高于散点图;否则我会发现相交,因此在某些地方看起来不连续。)
![3D bivariate scatter/hist](https://istack.dev59.com/vjlXA.webp)
最后,我认为这有点分散注意力(2D变体已经足够了):显示z轴意味着数据有第三个维度;特别是Tufte反对这种行为(Tufte,“Envisioning Information”,1990年)。但是,随着维数的增加,使用RGL的这种技术将允许更深入地了解模式。
(记录一下,Win7 x64,在32位和64位R-3.0.3上进行了测试,rgl v0.93.996,car v2.0-19。)