I would like to do the following
set.seed(1)
x <- seq(-10, 10, length= 600)
y <- x
f <- function(x, y) { r <- sqrt(x^2+y^2); 10 * sin(r)/r }
z <- outer(x, y, f)
persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "lightblue")
But the grid is too thin so the border dominates (You can confirm it is indeed the border and not the lighting by using border = NA
. It turns to blue):
One way to address this is of course to use not so fine of a grid (for example if you change length = 600
to length= 50
it looks very pleasant, and is actually the example in ?persp). But I want the same shape and smooth exactly as this fine grid. I just don't want to draw all of the borders, maybe only 1/5th of them for example (or half which I assume I can customize).
An issue with plotting the smooth shape and then plotting a grid over top of it is that you can see through the shape to the grid on the other side. To address this, you can start by plotting the course grid on top of a white object, meaning you can't see the back side of the grid, saving the result to a file.
x <- seq(-10, 10, length=50)
y <- x
z <- outer(x, y, f)
png("top.png")
print(persp(x, y, z, theta = 30, phi = 30, expand = 0.5, border="black", col="white"))
dev.off()
Then, you can plot smoothed image followed by the grid with all white colors fully transparent.
x <- seq(-10, 10, length= 600)
y <- x
f <- function(x, y) { r <- sqrt(x^2+y^2); 10 * sin(r)/r }
z <- outer(x, y, f)
png("bottom.png")
print(persp(x, y, z, theta = 30, phi = 30, expand = 0.5, border="lightblue", col="lightblue"))
dev.off()
par(oma=c(0, 0, 0, 0), mar=c(0, 0, 0, 0))
library(png)
top.img <- readPNG("top.png")
top.img[,,4][top.img[,,1] + top.img[,,2] + top.img[,,3] > 2] <- 0
plot.new()
rasterImage(bottom.img, 0, 0, 1, 1)
rasterImage(top.img, 0, 0, 1, 1)
I have got two solutions, but I think both of them are not exactly what you are searching for. I make a line overlay, but it doesn't get overlapped by the surface.
set.seed(1)
x <- seq(-10, 10, length= 600)
y <- x
f <- function(x, y) { r <- sqrt(x^2+y^2); 10 * sin(r)/r }
z <- outer(x, y, f)
persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "lightblue", border=NA, shade=0.75, ticktype = "detailed")
par(new=T)
set.seed(1)
x <- seq(-10, 10, length=20)
y <- x
f <- function(x, y) { r <- sqrt(x^2+y^2); 10 * sin(r)/r }
z <- outer(x, y, f)
persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = NA, border="green")
set.seed(1)
x <- seq(-10, 10, length= 600)
y <- x
f <- function(x, y) { r <- sqrt(x^2+y^2); 10 * sin(r)/r }
z <- outer(x, y, f)
res <- persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "lightblue", border=NA, shade=0.75, ticktype = "detailed")
library(grDevices)
xlines <- seq(1, length(x), length.out=20)
for(line in xlines){
lines (trans3d(x=x[line], y = y, z = z[line, ], pmat = res), col = 3, lwd=2)
}
ylines <- seq(1, length(y), length.out=20)
for(line in ylines){
lines (trans3d(x=x, y = y[line], z = z[,line], pmat = res), col = 3, lwd=2)
}
Here are two approaches, neither of which are not ideal. You can use NAs to force transparent "lines" onto the surface (Approach 1) or use NAs to get rid of all but the "grid lines" (Approach 2)
z2 <- z
lin.seq<- seq(10, 600, 10)
z2[lin.seq,] <- NA
z2[,lin.seq] <- NA
persp(x, y, z2, theta = 30, phi = 30, expand = 0.5,
border=NA, col="lightblue", box=TRUE)
You can then overlay plot above on a solid black surface:
# using original example data
persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "black", border=NA)
par(new=TRUE)
z2 <- z
lin.seq<- seq(10, 600, 10)
z2[lin.seq,] <- NA
z2[,lin.seq] <- NA
persp(x, y, z2, theta = 30, phi = 30, expand = 0.5,
border=NA, col="lightblue", box=FALSE)
# using original example data
persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "lightblue", border=NA)
z3 <- matrix(ncol=600, nrow=600) # NA matrix
lin.seq <- seq(25, 600, 25) # spacing of "grid lines"
lin.seq <- c(lin.seq, lin.seq-1, lin.seq-2) # to make lines a bit thicker
# replace some NAs on "grid lines" with values from z.
z3[lin.seq,] <- z[lin.seq,]
z3[,lin.seq] <- z[,lin.seq]
par(new=TRUE)
persp(x, y, z3, theta = 30, phi = 30, expand = 0.5,
border=NA, col="black", box=FALSE)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With