R: Plotting a 3D surface from x, y, z

匿名 (未验证) 提交于 2019-12-03 01:49:02

问题:

imagine I have a 3 columns matrix
x, y, z where z is a function of x and y.

I know how to plot a "scatter plot" of these points with plot3d(x,y,z)

But if I want a surface instead I must use other commands such as surface3d The problem is that it doesn't accept the same inputs as plot3d it seems to need a matrix with

How can I get this matrix? I've tried with the command interp, as I do when I need to use contour plots.

How can I plot a surface directly from x,y,z without calculating this matrix? If I had too many points this matrix would be too big.

cheers

回答1:

If your x and y coords are not on a grid then you need to interpolate your x,y,z surface onto one. You can do this with kriging using any of the geostatistics packages (geoR, gstat, others) or simpler techniques such as inverse distance weighting.

I'm guessing the 'interp' function you mention is from the akima package. Note that the output matrix is independent of the size of your input points. You could have 10000 points in your input and interpolate that onto a 10x10 grid if you wanted. By default akima::interp does it onto a 40x40 grid:

> require(akima) ; require(rgl) > x=runif(1000) > y=runif(1000) > z=rnorm(1000) > s=interp(x,y,z) > dim(s$z) [1] 40 40 > surface3d(s$x,s$y,s$z) 

That'll look spiky and rubbish because its random data. Hopefully your data isnt!



回答2:

You can use the function outer() to generate it.

Have a look at the demo for the function persp(), which is a base graphics function to draw perspective plots for surfaces.

Here is their first example:

x 

The same applies to surface3d():

require(rgl)   surface3d(x, y, z) 


回答3:

rgl is great, but takes a bit of experimentation to get the axes right.

If you have a lot of points, why not take a random sample from them, and then plot the resulting surface. You can add several surfaces all based on samples from the same data to see if the process of sampling is horribly affecting your data.

So, here is a pretty horrible function but it does what I think you want it to do (but without the sampling). Given a matrix (x, y, z) where z is the heights it will plot both the points and also a surface. Limitations are that there can only be one z for each (x,y) pair. So planes which loop back over themselves will cause problems.

The plot_points = T will plot the individual points from which the surface is made - this is useful to check that the surface and the points actually meet up. The plot_contour = T will plot a 2d contour plot below the 3d visualization. Set colour to rainbow to give pretty colours, anything else will set it to grey, but then you can alter the function to give a custom palette. This does the trick for me anyway, but I'm sure that it can be tidied up and optimized. The verbose = T prints out a lot of output which I use to debug the function as and when it breaks.

plot_rgl_model_a 

The add_rgl_model does the same job without the options, but overlays a surface onto the existing 3dplot.

add_rgl_model 

So my approach would be to, try to do it with all your data (I easily plot surfaces generated from ~15k points). If that doesn't work, take several smaller samples and plot them all at once using these functions.



回答4:

You could look at using Lattice. In this example I have defined a grid over which I want to plot z~x,y. It looks something like this. Note that most of the code is just building a 3D shape that I plot using the wireframe function.

The variables "b" and "s" could be x or y.

require(lattice)  # begin generating my 3D shape b 


回答5:

Maybe is late now but following Spacedman, did you try duplicate="strip" or any other option?

x=runif(1000) y=runif(1000) z=rnorm(1000) s=interp(x,y,z,duplicate="strip") surface3d(s$x,s$y,s$z,color="blue") points3d(s) 


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