tags:

views:

39

answers:

2

Hello

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

(nº elements of z) = (n of elements of x) * (n of elements of x)

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

A: 

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)
Matthieu Dubois
A: 

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!

Spacedman