How to plot a surface in rgl plot3d

偶尔善良 提交于 2019-12-24 07:15:32

问题


So I have this code that produces the exact surface

f = function(x, y){
    z = ((x^2)+(3*y^2))*exp(-(x^2)-(y^2))
}
plot3d(f, col = colorRampPalette(c("blue", "white")), 
       xlab = "X", ylab = "Y", zlab = "Z", 
       xlim = c(-3, 3), ylim = c(-3, 3),
       aspect = c(1, 1, 0.5))

Giving the following plot:

Now I have some code that does a random walk metropolis algorithm to reproduce the above image. I think it works as if I do another plot of these calculated values I get the next image with 500 points. Here is the code
open3d()
plot3d(x0, y0, f(x0, y0), type = "p")

Which gives the following plot:

I know it's hard looking at this still image but being able to rotate the sampling is working.

Now here is my question: How can I use plot3d() so that I can have a surface that connects all these points and gives a more jagged representation of the exact plot? Or how can I have each point in the z axis as a bar from the xy plane? I just want something more 3 dimensional than points and I can't find how to do this.

Thanks for your help


回答1:


You can do this by triangulating the surface. You don't give us your actual data, but I can create some similar data using

f = function(x, y){
    z = ((x^2)+(3*y^2))*exp(-(x^2)-(y^2))
}
x <- runif(500, -3, 3)
y <- runif(500, -3, 3)
z <- f(x, y)

Then the plotting is done using the method in ?persp3d.deldir:

library(deldir)
library(rgl)
col <- colorRampPalette(c("blue", "white"))(20)[1 + round(19*(z - min(z))/diff(range(z)))]
dxyz <- deldir::deldir(x, y, z = z, suppressMsge = TRUE)
persp3d(dxyz, col = col, front = "lines", back = "lines")

This might need some cosmetic fixes, e.g.

aspect3d(2, 2, 1)

After some rotation, this gives me the following plot:




回答2:


I'm not sure to understand what you want. If my understanding is correct, here is a solution. Define a parametric representation of your surface:

fx <- function(u,v) u
fy <- function(u,v) v
fz <- function(u,v){
  ((u^2)+(3*v^2))*exp(-(u^2)-(v^2))
}

Let's say you have these points:

x0 <- seq(-3, 3, length.out = 20)
y0 <- seq(-3, 3, length.out = 20)

Then you can use the function parametric3d of the misc3d package, with the option fill=FALSE to get a wireframe:

library(misc3d)
parametric3d(fx, fy, fz, u=x0, v=y0, 
             color="blue", fill = FALSE)

Is it what you want?

To get some vertical bars, use the function segments3d of rgl:

i <- 8
bar <- rbind(c(x0[i],y0[i],0),c(x0[i],y0[i],f(x0[i],y0[i])))
segments3d(bar, color="red")



回答3:


Here is a plot with only 50 points using my original code.

When I then apply what was said by Stéphane Laurent I then get this plot which feels too accurate when given the actual points I have

Perhaps you need to explain to me what is actually happening in the function parametric3d



来源:https://stackoverflow.com/questions/53398108/how-to-plot-a-surface-in-rgl-plot3d

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!