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

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


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 40surface3d(s$x,s$y,s$z)

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


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 <- seq(-10, 10, length.out = 50)  y <- x  rotsinc <- function(x,y) {    sinc <- function(x) { y <- sin(x)/x ; y[is.na(y)] <- 1; y }      10 * sinc( sqrt(x^2+y^2) )  }z <- outer(x, y, rotsinc)  persp(x, y, z)

The same applies to surface3d():

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


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 shapeb <- seq(from=0, to=20,by=0.5)s <- seq(from=0, to=20,by=0.5)payoff <- expand.grid(b=b,s=s)payoff$payoff <- payoff$b - payoff$spayoff$payoff[payoff$payoff < -1] <- -1# end generating my 3D shapewireframe(payoff ~ s * b, payoff, shade = TRUE, aspect = c(1, 1),    light.source = c(10,10,10), main = "Study 1",    scales = list(z.ticks=5,arrows=FALSE, col="black", font=10, tck=0.5),    screen = list(z = 40, x = -75, y = 0))