基于数据框的RGL表面图绘制

3

我使用scatter3d()Rcmdr创建了一个漂亮的图表。该图表包含两个漂亮的表面平滑。现在我想要添加另一个表面到这个图表中,真实表面(即由生成观测值的函数减去噪声成分定义的表面)。

以下是我目前的代码:

library(car) 
set.seed(1)

n <- 200 # number of observations (x,y,z) to be generated
sd <- 0.3 # standard deviation for error term
x <- runif(n) # generate x component
y <- runif(n) # generate y component

r <- sqrt(x^2+y^2) # used to compute z values

z_t <- sin(x^2+3*y^2)/(0.1+r^2) + (x^2+5*y^2)*exp(1-r^2)/2 # calculate values of true regression function

z <-  z_t + rnorm(n, sd = sd) # overlay normally distrbuted 'noise' 
dm <- data.frame(x=x, y=y, z=z) # data frame containing (x,y,z) observations
dm_t <- data.frame(x=x,y=y, z=z_t) # data frame containing (x,y) observations and the corresponding value of the *true* regression function

# Create 3D scatterplot of:
# - Observations (this includes 'noise')
# - Surface given by Additive Model fit 
# - Surface given by bivariate smoother fit

scatter3d(dm$x, dm$y, dm$z, fit=c("smooth","additive"), bg="white", 
          axis.scales=TRUE, grid=TRUE, ellipsoid=FALSE, xlab="x", ylab="z", zlab="y")

在另一个帖子中提出的解决方案是定义一个函数:
my_surface <- function(f, n=10, ...) { 
  ranges <- rgl:::.getRanges()
  x <- seq(ranges$xlim[1], ranges$xlim[2], length=n)
  y <- seq(ranges$ylim[1], ranges$ylim[2], length=n)
  z <- outer(x,y,f)
  surface3d(x, y, z, ...)
}

f <- function(x, y)
  sin(x^2+3*y^2)/(0.1+r^2) + (x^2+5*y^2)*exp(1-r^2)/2

my_surface(f, alpha=0.2)

然而,这会产生一个错误,错误信息如下(翻译自德语,因为这是我的系统语言,我很抱歉):
Error in outer(x, y, f) : 
  Dimension [Product 100] does not match the length of the object [200]

我尝试了另一种方法:
x <- seq(0,1,length=20)
y <- x
z <- outer(x,y,f)
surface3d(x,y,z)

这确实增加了我的图表面积,但它看起来一点也不对(即观测值与其根本不接近)。这是所谓的真实曲面的样子(显然是错误的):感谢您!
我认为问题可能实际上是比例尺的问题。在这里,我创建了几个位于平面 z = x+y 上的点。然后我尝试使用上述方法绘制该平面:
library(car)

n <- 50
x <- runif(n)
y <- runif(n)
z <- x+y

scatter3d(x,y,z, surface = FALSE)

f <- function(x,y) 
  x + y 

x_grid <- seq(0,1, length=20)
y_grid <- x_grid 
z_grid <- outer(x_grid, y_grid, f)
surface3d(x_grid, y_grid, z_grid)

这给我呈现出下面的图表:

缩放问题

也许你们中的某个人能够帮我解决这个问题?

3
你曾提出过类似的问题,并得到了一个好的答案,但你从未投票或接受过答案。这会让人们不愿意帮助你,因为你没有为社区做出贡献。请阅读帮助关于页面,了解 SO 应该如何运作。请注意保持原文意思,使其更通俗易懂。 - Simon O'Hanlon
@HaskellElephant 我从未谈论过我的选择。我只是指出,当用户从未指出问题时,其他人可能不愿意帮助。你从哪里得出这个结论的?除此之外,在我留下评论的那一刻,该问题没有包含任何代码和可重现的示例。现在我看到OP留下了一个很好的可重现的示例,并且对社区有了更好的认识,因为他们接受了一个答案(根据他们自己的承认解决了他们的问题)。因此,我的评论丰富了社区和OP的经验。更多的参与=更好的结果。 - Simon O'Hanlon
1
感谢您花时间编辑这个问题,现在它成为了一个很好的可重现的例子。 - Simon O'Hanlon
1个回答

0

car 中的 scatter3d 函数在绘制数据之前会重新调整其比例,这使得它与基本上所有的 rgl 绘图函数不兼容,包括 surface3d

您可以使用所有的 rgl 函数(例如 plot3d(x, y, z))代替 scatter3d 来获得类似于所需的绘图,但是它将具有 rgl 风格的坐标轴而不是 car 风格的坐标轴。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接