原始标题(模糊):如何仅从x和z值制作圆形曲面
我有与x轴和z轴相关的数据,类似于new.data
的值:
mydata <- structure(list(Dist = c(82, 82, 85, 85, 126, 126, 126, 126, 178,
178, 178, 178, 178, 236, 236, 236, 236, 236, 312, 368, 368, 368,
368, 368, 425, 425, 425, 425, 425, 425, 560, 560, 560, 560, 560,
612, 612, 612, 612), pDet = c(1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0,
1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0)), .Names = c("Dist", "pDet"), row.names = c(NA,
-39L), class = "data.frame")
model <- glm(pDet ~ Dist, data = mydata, family = binomial(link = "logit"))
new.data <- data.frame(Dist = seq(0, 650, 50))
new.data$fit <- predict(model, newdata = new.data, type="response")
我想生成一个表面/矩阵,其中new.data$fit
的值代表z轴,而x轴和y轴是从半径new.data$Dist
生成的。
换句话说,我想要一个从半径Dist
生成的圆和由z
逻辑概率曲线值填充的单元格。我想说我已尝试过某些解决方案,但甚至不知道从哪里开始。
答案 0 :(得分:4)
因此,您希望通过围绕垂直线Dist = 0
旋转逻辑曲线来绘制surface of revolution。 统计上我不知道为什么我们需要这个,但纯粹从数学方面来说,为了3D可视化,这有点有用,因此我决定回答这个问题。
我们所需要的只是初始2D曲线f(d)
的函数,其中d
是从点到旋转中心的距离,f
是一些平滑函数。由于我们将使用outer
来制作曲面矩阵,因此必须将f
定义为R中的矢量化函数。现在,旋转曲面生成为f3d(x, y) = f((x ^ 2 + y ^ 2) ^ 0.5)
。
在逻辑回归设置中,上面的f
是逻辑曲线,即GLM的预测响应。它可以从predict.glm
获得,它是一个矢量化函数。以下代码适合模型,并定义此类函数f
及其3D扩展。
mydata <- structure(list(Dist = c(82, 82, 85, 85, 126, 126, 126, 126, 178,
178, 178, 178, 178, 236, 236, 236, 236, 236, 312, 368, 368, 368,
368, 368, 425, 425, 425, 425, 425, 425, 560, 560, 560, 560, 560,
612, 612, 612, 612), pDet = c(1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0,
1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0)), .Names = c("Dist", "pDet"), row.names = c(NA,
-39L), class = "data.frame")
model <- glm(pDet ~ Dist, data = mydata, family = binomial(link = "logit"))
## original 2D curve
f <- function (d, glmObject)
unname(predict.glm(glmObject, newdata = list(Dist = d), type = "response"))
## 3d surface function on `(x, y)`
f3d <- function (x, y, glmObject) {
d <- sqrt(x ^ 2 + y ^ 2)
f(d, glmObject)
}
由于对称性,我们只在表面矩阵f3d
的第一象限上调用X1
,而在其他象限上翻转X1
表面矩阵。
## prediction on the 1st quadrant
x1 <- seq(0, 650, by = 50)
X1 <- outer(x1, x1, FUN = f3d, glmObject = model)
## prediction on the 2nd quadrant
X2 <- X1[nrow(X1):2, ]
## prediction on the 3rd quadrant
X3 <- X2[, ncol(X2):2]
## prediction on the 4th quadrant
X4 <- X1[, ncol(X1):2]
最后,我们组合来自不同象限的矩阵并制作3D图。请注意,组合顺序是象限3-4-2-1。
## combined grid
x <- c(-rev(x1), x1[-1])
# [1] -650 -600 -550 -500 -450 -400 -350 -300 -250 -200 -150 -100 -50 0 50
#[16] 100 150 200 250 300 350 400 450 500 550 600 650
## combined matrix
X <- cbind(rbind(X3, X4), rbind(X2, X1))
## make 3D surface plot
persp(x, x, X, col = "lightblue", theta = 35, phi = 40,
xlab = "", ylab = "", zlab = "pDet")
制作玩具例程以绘制革命表面
在这部分中,我们定义了一个用于绘制旋转表面的玩具程序。如上所述,我们需要这个例程:
f
; {(x, y) | x >= 0, y >= 0}
上的评估网格(由于我们采用对称性y = x
); f
可能的其他参数,以及persp
的自定义图形参数。以下是一个简单的实现:
surfrev <- function (f, x, args.f = list(), ...) {
## extend `f` to 3D
.f3d <- function (x, y) do.call(f, c(list(sqrt(x ^ 2 + y ^ 2)), args.f))
## surface evaluation
X1 <- outer(x, x, FUN = .f3d)
X2 <- X1[nrow(X1):2, ]
X3 <- X2[, ncol(X2):2]
X4 <- X1[, ncol(X1):2]
xbind <- c(-rev(x), x[-1])
X <- cbind(rbind(X3, X4), rbind(X2, X1))
## surface plot
persp(xbind, xbind, X, ...)
## invisible return
invisible(list(grid = xbind, z = X))
}
现在假设我们想在[0, pi]
上旋转一个余弦波来表示旋转表面,我们可以做到
surfrev(cos, seq(0, pi, by = 0.1 * pi), col = "lightblue", theta = 35, phi = 40,
xlab = "", ylab = "", zlab = "")
我们也可以使用surfrev
绘制您想要的逻辑曲线:
## `f` and `model` defined at the beginning
surfrev(f, seq(0, 650, by = 50), args.f = list(glmObject = quote(model)),
col = "lightblue", theta = 35, phi = 40, xlab = "", ylab = "", zlab = "")