Is there a way to increase a 3D surface plot thickness like the plots here using the persp3D()
function in the plot3D
package in R? Can't seem to find anything in the documentation.
Asked
Active
Viewed 434 times
2

Werner Hertzog
- 2,002
- 3
- 24
- 36

user2566907
- 99
- 10
2 Answers
3
I was able to get this to work by creating multiple surfaces and connecting them using the curtain
argument of the plot3D function. The thickness was controlled by the z
argument of each surface. In case anyone needs the sample code, here it is;
For simplicity, I used meters to specify thicknesses/height of the surfaces
library(plot3D)
library(plot3Drgl)
# volcano data range
clim <- range(volcano)
# Surface 1
persp3D(z = volcano, zlim = c(0, 600), clim = clim,
box = FALSE, plot = FALSE, curtain = TRUE, border = "black")
# Surface 2 - 20m below surface 1
persp3D(z = volcano - 20, clim = clim, colvar = volcano,
add = TRUE, colkey = FALSE, plot = FALSE, curtain = TRUE, border = "black")
# Surface 3 - 40m below surface 1
persp3D(z = volcano - 40, clim = clim, colvar = volcano,
add = TRUE, colkey = FALSE, plot = FALSE, curtain = TRUE, border = "black")
# Surface 4 - 60m below surface 1
persp3D(z = volcano - 60, clim = clim, colvar = volcano,
add = TRUE, colkey = FALSE, plot = TRUE, curtain = TRUE, border = "black")
# Surface 5 - 80m below surface 1
persp3D(z = volcano - 80, clim = clim, colvar = volcano,
add = TRUE, colkey = FALSE, plot = TRUE, curtain = FALSE, border = "black")
# Open rgl for interactive viewing
plotrgl()

user2554330
- 37,248
- 4
- 43
- 90

user2566907
- 99
- 10
-
That's nice looking. (I added the `library()` calls to make it easier for others to use.) – user2554330 Mar 30 '18 at 20:40
1
I don't know about plot3D
, but rgl
doesn't have a specific function for that. The way to do it is to calculate the polygons corresponding to the edges of the slab, and use polygon3d
to plot those. For example:
data(volcano)
persp3d(volcano, col = "green")
# The bottom of the slab
persp3d(volcano-10, col = "blue", add = TRUE)
minx <- 0
maxx <- 1
miny <- 0
maxy <- 1
m <- nrow(volcano)
n <- ncol(volcano)
# The front edge
edgex <- c(seq(minx, maxx, length.out = m),
seq(maxx, minx, length.out = m))
edgey <- miny
edgez <- c(volcano[,1],rev(volcano[,1] - 10))
polygon3d(cbind(edgex, edgey, edgez), coords = c(1,3),
col = "yellow")
# The back edge
edgey <- maxy
edgez <- c(volcano[,n],rev(volcano[,n] - 10))
polygon3d(cbind(edgex, edgey, edgez), coords = c(1,3), col = "white")
edgex <- minx
edgey <- c(seq(miny, maxy, length.out = n),
seq(maxy, miny, length.out = n))
edgez <- c(volcano[1,],rev(volcano[1,] - 10))
polygon3d(cbind(edgex, edgey, edgez), coords = c(2,3), col = "black")
edgex <- maxx
edgez <- c(volcano[m,],rev(volcano[m,] - 10))
polygon3d(cbind(edgex, edgey, edgez), coords = c(2,3), col = "green")

user2554330
- 37,248
- 4
- 43
- 90
-
Thanks for the response, @user2554330. I encountered the following error `Error in processOutside(i) : Cannot triangulate polygon` when I ran `polygon3d(cbind(edgex, edgey, edgez), coords = c(2,3), col = "black")` and `polygon3d(cbind(edgex, edgey, edgez), coords = c(1,3), col = "yellow")`. I have tried to fix the code but to no avail. – user2566907 Mar 29 '18 at 00:44
-
Yes, the algorithm for triangulation can fail. Generally if you try again it will work, as it normally has a random component. However, if the polygon is set up incorrectly it might never succeed, so it's worth checking your edge vectors, e.g. by calling `plot(edgex, edgez, type="l")` if you're having trouble. – user2554330 Mar 29 '18 at 10:23
-
Thank you very much @user2554330. I'll play around with the vectors. – user2566907 Mar 29 '18 at 22:35