Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

plot

r

matrix

3d

rgl

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

like image 256
skan Avatar asked Oct 20 '10 14:10

skan


People also ask

How do you plot a 3D plot in R?

Creating 3D Plots in R Programming – persp() Function 3D plot in R Language is used to add title, change viewing direction, and add color and shade to the plot. The persp() function which is used to create 3D surfaces in perspective view. This function will draw perspective plots of a surface over the x–y plane.

How do you make a surface plot in R?

The surface is built up from first principles as follows: we consider two open intervals U = {u: ∈ (0 , 2π )} and V = {v: ∈ (0 , π )}, lay down a mesh or grid over the two dimensional open set U x V, compute the parametric representation of the surface in R3 , and use the surf3D() function from the plot3D package to ...


3 Answers

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!

like image 100
Spacedman Avatar answered Oct 06 '22 05:10

Spacedman


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)
like image 38
Matthieu Dubois Avatar answered Oct 06 '22 05:10

Matthieu Dubois


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 <- 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$s
payoff$payoff[payoff$payoff < -1] <- -1
# end generating my 3D shape


wireframe(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))
like image 21
Aaron Avatar answered Oct 06 '22 06:10

Aaron