Search code examples
r3dsurfacerglgeometry-surface

Insert "cut off" field in R surface plot


I'm using persp() to create a 3d plot (but I'm open to anything that will get the job done). Now I want to add a 2d field to make it clear where the 3d plot is above a specific Z value. Is there a way to achieve this? Ideally it would ideally be something like a semi transparent surface where you can see the mass under the surface vs over.

Using the example from the persp documentation

f <- function(x, y) { r <- sqrt(x^2+y^2); 10 * sin(r)/r }

x <- seq(-10, 10, length= 30)
y <- x
z <- outer(x, y, f)
z[is.na(z)] <- 1

persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "lightblue",
      ltheta = 120, shade = 0.75, ticktype = "detailed",
      xlab = "X", ylab = "Y", zlab = "Sinc( r )"
) 

How can I insert a field that slices the graph at a certain point of the z-axis?


Solution

  • How about this - there are a lot more possibilities using the rgl package, but it has a persp3d function for easy upgrade from the base graphics.

    library(rgl)
    
    f <- function(x, y) { r <- sqrt(x^2+y^2); 10 * sin(r)/r }
    x <- seq(-10, 10, length= 30)
    y <- x
    z <- outer(x, y, f)
    z[is.na(z)] <- 1
    
    persp3d(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "lightblue",
          ltheta = 120, shade = 0.75, ticktype = "detailed",
          xlab = "X", ylab = "Y", zlab = "Sinc( r )")
    
    # Here we add a transparent purple square to mark the top
    
    # x and y mark the corners of the purple square, z is its height
    sqdf <- data.frame(x=c(-10,-10,10,10,-10),
                       y=c(-10, 10,10,-10,-10),
                       z=c(5,5,5,5,5))
    
    # now draw the purple square, 
    #    note:
    #    -  the "add=T" parameter that appends it to the previous 3d-plot
    #    -  the coord paramter tells it what two planes to use when 
    #        tesselating the polygon into triangles 
    #        (a necessary step and expensive to calculate)
    
    polygon3d(sqdf$x,sqdf$y,sqdf$z,coord=c(1,2),alpha=0.5,color="purple",add=T)
    

    Yielding:

    enter image description here