rplot3drgl

How to increase the space between grid lines in rgl::surface3d?


I do 3d plots with the rgl package. Here is some code:

# Plot function.
my_plot <- function(x, y, z){
  colours <- heat.colors(length(unique(z))); minval <- min(z); maxval <- max(z) + 10
  col <- colours[(z - minval)/(maxval - minval)*99 + 1]
  rgl::persp3d(x, y, z, col= col) 
  rgl::surface3d(x, y, z, front = "lines")
  rgl::surface3d(x, y, z, back = "lines")
}

# Dummy data.
x <- seq(-2, 2, length = 7) 
y <- seq(-3, 3, length = 5)  # I've chosen different ranges 
z <- outer(x, y, function(x, y) x + y^2)

# Make a plot.
my_plot(x, y, z)

big space

This plot looks nice to me. However, the space between the grid lines depends on the scale of the input data. If we generate data with smaller steps in seq then the plot looks different:

x <- seq(-2, 2, length = 100) 
y <- seq(-3, 3, length = 100)  # I've chosen different ranges 
z <- outer(x, y, function(x, y) x + y^2)
my_plot(x, y, z)

narrow grid

My actual data has tiny steps in x and y, so that the resulting grid lines are really narrow. How can I adapt the space the grid lines? What I am looking for is something like the resfac argument in plot3D::persp3D (unfortunately, plot3D has different other drawbacks and this is why I want to stick to rgl package). In other words: How can we get the wider spaced grid lines as in the upper plot for the second dummy data with small steps in x and y?


Solution

  • A comment suggested subsetting the surface, but that won't work because the lines won't fall within the curved solid part. The way to do this is to draw the grid lines "manually". Here's an example:

    library(rgl)
    my_plot <- function(x, y, z, numLines = 6){
      colours <- heat.colors(100); minval <- min(z); maxval <- max(z)
      col <- colours[(z - minval)/(maxval - minval)*99 + 1]
      dim(col) <- dim(z)
      rgl::persp3d(x, y, z, col= col, polygon_offset = 1) 
     
      numLines <- rep_len(numLines, 2)
      xind <- round(seq(1, length(x), length.out = numLines[1]))
      yind <- round(seq(1, length(y), length.out = numLines[2]))
      for (i in xind)
        lines3d(x[i], y, z[i,], col = "black")
      for (j in yind)
        lines3d(x, y[j], z[,j], col = "black")
    }
    
    x <- seq(-2, 2, length = 100) 
    y <- seq(-3, 3, length = 100)  # I've chosen different ranges 
    z <- outer(x, y, function(x, y) x + y^2)
    my_plot(x, y, z)
    

    enter image description here