Skip to content

persp plot + plotting grid lines

7 messages · Pedro Mardones, David Winsemius, Kingsford Jones +1 more

#
Dear all;
Does anyone know how to add grid lines to a persp plot? I've tried
using lines(trans3d..) but the lines of course are superimposed into
the actual 3d surface and what I need is something like the plot shown
in the following link:
http://thermal.gg.utah.edu/tutorials/matlab/matlab_tutorial.html
I'll appreciate any ideas
Thanks
PM
#
Ideas... not a solution. Plot the grid within your ranges using  
something along the lines, literally and figuratively, based on the  
second example of persp's help pages. For the z=8 grid lines on that  
example you could use:

for (ix in seq(-10,10, by=5)) lines (trans3d(x=ix, y=seq(-10,10,  
by=5), z= 8, pmat = res),
                                               col = "red",  
lty="dotted")
for (iy in seq(-10,10, by=5)) lines (trans3d(x=seq(-10,10, by=5),  
y=iy, z= 8, pmat = res),
                                               col = "red",  
lty="dotted")

#for some reason using x and y in the for-loops "contaminated" the x  
and y values in the calling environment. I did not think that was  
supposed to happen.

The concern I see is that the height of the lines and the relation to  
the surface is not apparent to the viewer and the the persp function  
says it ignores transparent colors. I find that contour plots are less  
ambiguous and that the persp plots are most useful for qualitative  
shapes rather than quantitative extraction of inferences. Perhaps in  
your example (not provided) you could draw the grid lines somewhat  
lower and then re-plot plot the surface after plotting the gridlines.  
Since I have not mastered the manner in which persp can be convinced  
to not plot over an existing device in the regions where it has no  
surface, I cannot provide the final steps of that process. The par  
help page describing new= does not make sense to me, and trying both  
TRUE and FALSE fails to achieve the desired results.

One guess is that the way forward might be to adapt the example the  
Sarkar provides at the end of his Lattice book with Figure 13.7:
http://lmdvr.r-forge.r-project.org/figures/figures.html

Or to condition the width of line segments on whether or not they were  
above or below the z-value at z[x=seq(),iy]  or <something else>.?
#
On Mar 14, 2009, at 12:02 PM, Pedro Mardones wrote:

            
I also see that Ben Bolker offered such code to those who requested it  
in this r-help posting from a year or so ago. You might try emailing  
him. Also note that Deepayan Sarkar suggested wireframe might be  
easier to work with.

http://finzi.psych.upenn.edu/R/Rhelp02/archive/116908.html
#
On 14/03/2009 12:02 PM, Pedro Mardones wrote:
I just posted a couple of demos of this using the rgl function persp3d, 
in the thread "Re: [R] can I draw 3D plot like this using R?".

Duncan Murdoch
#
This wiki page has the answer. Draw the plot first to establish the  
coordinate system and create the viewing transformation matrix. Draw  
the grid lines with lines(trans3d()), and then put a:

par(new=T) ... and then redraw the plot over the gridlines.

<http://wiki.r-project.org/rwiki/doku.php?id=tips:graphics- 
base:add_grid>

################
x <- seq(-10, 10, length= 30)
y <- x
f <- function(x,y) { r <- sqrt(x^2+y^2); 10 * sin(r)/r }
z <- outer(x, y, f)
z[is.na(z)] <- 1
op <- par(bg = "white")
  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 )"
) -> res

for (ix in seq(-10,10, by=5)) lines (trans3d(x=ix, y=seq(-10,10,  
by=5), z= -10, pmat = res),
                                              col = "red", lty="dotted")
for (iy in seq(-10,10, by=5)) lines (trans3d(x=seq(-10,10, by=5),  
y=iy, z= -10, pmat = res),
                                              col = "red", lty="dotted")
for (ix in seq(-10,10, by=5)) lines (trans3d(x=ix, y=10, z=  
seq(-10,10, by=5), pmat = res),
                                              col = "red", lty="dotted")
for (iz in seq(-10,10, by=5)) lines (trans3d(x=seq(-10,10, by=5),  
y=10, z= iz, pmat = res),
                                              col = "red", lty="dotted")
  for (iy in seq(-10,10, by=5)) {lines (trans3d(x=-10, y=iy, z=  
seq(-10,10, by=5), pmat = res),
                                               col = "red",  
lty="dotted")}
  for (iz in seq(-10,10, by=5)) {lines (trans3d(x=-10, y=seq(-10,10,  
by=5), z= iz, pmat = res),
                                               col = "red",  
lty="dotted")}
  par(new=T)
  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 )")
par(op)
#
Building on Duncan's code, here's an approximation to the Matlab
'peaks' plot referred to by Pedro:

peaks <-  function(x, y) { 3 * (1-x)^2 * exp(-(x^2)-(y+1)^2) -
  10 * (x/5-x^3-y^5) * exp(-x^2-y^2) - 1/3*exp(-(x+1)^2-y^2)}

x <- y <- seq(-3,3,.1)
z <- outer(x,y, peaks)
z2 <- 10 * round(c(z) + abs(min(z)) + 1)
jet.colors = colorRampPalette(c("#00007F", "blue", "#007FFF",
    "cyan", "#7FFF7F", "yellow", "#FF7F00", "red", "#7F0000"))
color <- jet.colors(160)[z2]

library(rgl)
persp3d(x,y,z, color=color, smooth=FALSE)
surface3d(x,y,z+0.001, front="lines", back="culled")



Kingsford Jones
On Sat, Mar 14, 2009 at 3:51 PM, Duncan Murdoch <murdoch at stats.uwo.ca> wrote:
#
On 15/03/2009 10:07 AM, Kingsford Jones wrote:
Using the textured grid as in my second option looks a bit better here.

The other big difference between rgl output and the Matlab output is 
that Matlab's looks flat, whereas rgl does some fairly complicated 
lighting calculations.  But if you don't want the shiny plastic look, 
you can partially turn it off by including the following:

persp3d(x,y,z, color=color, smooth=FALSE, specular="black")

Or turn it off completely with

persp3d(x,y,z, color=color, smooth=FALSE, lit = FALSE)