[R] Layering multiple persp plots

Stefan Evert stefanML at collocations.de
Wed Aug 4 01:27:08 CEST 2010


On 30 Jul 2010, at 19:22, Ian Bentley wrote:

> I've got two persp plots with Identical X and Y's, and I'd like to plot them
> on the same graph, so that it is obvious where one plot is above the other.
> I can't find any mention of this anywhere.  Do I need to use wireframe?

You can do it with wireframe() from the lattice package if you put in some manual tweaking and if you can live with simple wireframe plots in b/w (since the lattice 3D functions don't have a Z-buffer to handle polygon intersections correctly).  Such plots tend to get rather confusing, but stereographic viewing usually helps.

Animated 3D with rgl is much nicer in general, but the wireframe() trick allows you to produce high-quality b/w printouts.

The example below generates a stereographic plot of two intersecting surfaces for cross-eyed viewing (i.e. you have to look at the _left_ image with your _right_ eye and vice versa).

Hope this helps,
Stefan





library("lattice")

## set up viewport (turn=rectascension, elevation=declination, stereo=angle between eyes, distance=1/d)
turn <- 30
elevation <- 25
stereo <- 4
distance <- .2

## other display and graph properties 
xlim <- c(-4, 4)           # plot range on x-axis, y-axis and z-axis
ylim <- c(-4, 4)
zlim <- c(-2, 18)
grid <- 25                 # number of grid points for wireframe surfaces
coarse.grid <- 10          # number of grid points for coarser wireframe surface
zoom <- 1                  # zoom factor for graphs (to fit labels into panels)

view.left <- list(x=-90, y=turn-stereo/2, x=elevation)    # for RIGHT eye
view.right <- list(x=-90, y=turn+stereo/2, x=elevation)   # for LEFT eye
pos.left <- c(0,0,0.5,1)
pos.right <- c(0.5,0,1,1)

trellis.device(width=12, height=6, color=FALSE)
trellis.par.set("fontsize", list(text=16, points=10))
trellis.par.set("superpose.symbol", list(pch=20,cex=0.5))
trellis.par.set("axis.line", list(col="transparent")) # avoids frames around panels

grid1 <- expand.grid(x=seq(xlim[1],xlim[2],length=grid), y=seq(ylim[1],ylim[2],length=grid))
grid2 <- expand.grid(x=seq(xlim[1],xlim[2],length=coarse.grid), y=seq(ylim[1],ylim[2],length=coarse.grid))

# construct trellis objects for wireframe plots of different surfaces
wf1L <- wireframe(I(x*x + y*y) ~ x * y, data=grid1, screen=view.left, col.regions="transparent", distance=distance, zoom=zoom, xlim=xlim, ylim=ylim, zlim=zlim, xlab="x", ylab="y", zlab="z") # elevation of first surface (fine grid)
wf1R <- wireframe(I(x*x + y*y) ~ x * y, data=grid1, screen=view.right, col.regions="transparent", distance=distance, zoom=zoom, xlim=xlim, ylim=ylim, zlim=zlim, xlab="x", ylab="y", zlab="z") # elevation of first surface (fine grid)

wf2L <- wireframe(I(8 + 2*x) ~ x * y, data=grid2, screen=view.left, col.regions="transparent", distance=distance, zoom=zoom, xlim=xlim, ylim=ylim, zlim=zlim, xlab="x", ylab="y", zlab="z") # elevation of first surface (fine grid)
wf2R <- wireframe(I(8 + 2*x) ~ x * y, data=grid2, screen=view.right, col.regions="transparent", distance=distance, zoom=zoom, xlim=xlim, ylim=ylim, zlim=zlim, xlab="x", ylab="y", zlab="z") # elevation of first surface (fine grid)

# now overplot all four wireframes
print(wf1L, position=pos.left, more=TRUE)
print(wf1R, position=pos.right, more=TRUE)
print(wf2L, position=pos.left, more=TRUE)
print(wf2R, position=pos.right, more=FALSE)



More information about the R-help mailing list