This function draws perspective plots of a surface over the
x–y plane. persp
is a generic function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14  persp(x, ...)
## Default S3 method:
persp(x = seq(0, 1, length.out = nrow(z)),
y = seq(0, 1, length.out = ncol(z)),
z, xlim = range(x), ylim = range(y),
zlim = range(z, na.rm = TRUE),
xlab = NULL, ylab = NULL, zlab = NULL,
main = NULL, sub = NULL,
theta = 0, phi = 15, r = sqrt(3), d = 1,
scale = TRUE, expand = 1,
col = "white", border = NULL, ltheta = 135, lphi = 0,
shade = NA, box = TRUE, axes = TRUE, nticks = 5,
ticktype = "simple", ...)

x, y 
locations of grid lines at which the values in 
z 
a matrix containing the values to be plotted ( 
xlim, ylim, zlim 
x, y and zlimits. These should be chosen to cover the range of values of the surface: see ‘Details’. 
xlab, ylab, zlab 
titles for the axes. N.B. These must be character strings; expressions are not accepted. Numbers will be coerced to character strings. 
main, sub 
main and sub title, as for 
theta, phi 
angles defining the viewing direction.

r 
the distance of the eyepoint from the centre of the plotting box. 
d 
a value which can be used to vary the strength of
the perspective transformation. Values of 
scale 
before viewing the x, y and z coordinates of the
points defining the surface are transformed to the interval
[0,1]. If 
expand 
a expansion factor applied to the 
col 
the color(s) of the surface facets. Transparent colours are ignored. This is recycled to the (nx1)(ny1) facets. 
border 
the color of the line drawn around the surface facets.
The default, 
ltheta, lphi 
if finite values are specified for 
shade 
the shade at a surface facet is computed as

box 
should the bounding box for the surface be displayed.
The default is 
axes 
should ticks and labels be added to the box. The
default is 
ticktype 
character: 
nticks 
the (approximate) number of tick marks to draw on the
axes. Has no effect if 
... 
additional graphical parameters (see 
The plots are produced by first transforming the (x,y,z)
coordinates to the interval [0,1] using the limits supplied or
computed from the range of the data. The surface is then viewed
by looking at the origin from a direction defined by theta
and phi
. If theta
and phi
are both zero
the viewing direction is directly down the negative y axis.
Changing theta
will vary the azimuth and changing phi
the colatitude.
There is a hook called "persp"
(see setHook
)
called after the plot is completed, which is used in the
testing code to annotate the plot page. The hook function(s) are
called with no argument.
Notice that persp
interprets the z
matrix as a table of
f(x[i], y[j])
values, so that the x axis corresponds to row
number and the y axis to column number, with column 1 at the bottom,
so that with the standard rotation angles, the top left corner of the
matrix is displayed at the left hand side, closest to the user.
The sizes and fonts of the axis labels and the annotations for
ticktype = "detailed"
are controlled by graphics parameters
"cex.lab"
/"font.lab"
and
"cex.axis"
/"font.axis"
respectively.
The bounding box is drawn with edges of faces facing away from the viewer (and hence at the back of the box) with solid lines and other edges dashed and on top of the surface. This (and the plotting of the axes) assumes that the axis limits are chosen so that the surface is within the box, and the function will warn if this is not the case.
persp()
returns the viewing transformation matrix, say
VT
, a 4 x 4 matrix suitable for projecting 3D
coordinates (x,y,z) into the 2D plane using homogeneous 4D
coordinates (x,y,z,t). It can be used to superimpose
additional graphical elements on the 3D plot, by
lines()
or points()
, using the
function trans3d()
.
Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language. Wadsworth & Brooks/Cole.
contour
and image
; trans3d
.
Rotatable 3D plots can be produced by package rgl: other ways to produce static perspective plots are available in packages lattice and scatterplot3d.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63  require(grDevices) # for trans3d
## More examples in demo(persp) !!
## 
# (1) The Obligatory Mathematical surface.
# Rotated sinc function.
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")
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
round(res, 3)
# (2) Add to existing persp plot  using trans3d() :
xE < c(10,10); xy < expand.grid(xE, xE)
points(trans3d(xy[,1], xy[,2], 6, pmat = res), col = 2, pch = 16)
lines (trans3d(x, y = 10, z = 6 + sin(x), pmat = res), col = 3)
phi < seq(0, 2*pi, len = 201)
r1 < 7.725 # radius of 2nd maximum
xr < r1 * cos(phi)
yr < r1 * sin(phi)
lines(trans3d(xr,yr, f(xr,yr), res), col = "pink", lwd = 2)
## (no hidden lines)
# (3) Visualizing a simple DEM model
z < 2 * volcano # Exaggerate the relief
x < 10 * (1:nrow(z)) # 10 meter spacing (S to N)
y < 10 * (1:ncol(z)) # 10 meter spacing (E to W)
## Don't draw the grid lines : border = NA
par(bg = "slategray")
persp(x, y, z, theta = 135, phi = 30, col = "green3", scale = FALSE,
ltheta = 120, shade = 0.75, border = NA, box = FALSE)
# (4) Surface colours corresponding to zvalues
par(bg = "white")
x < seq(1.95, 1.95, length = 30)
y < seq(1.95, 1.95, length = 35)
z < outer(x, y, function(a, b) a*b^2)
nrz < nrow(z)
ncz < ncol(z)
# Create a function interpolating colors in the range of specified colors
jet.colors < colorRampPalette( c("blue", "green") )
# Generate the desired number of colors from this palette
nbcol < 100
color < jet.colors(nbcol)
# Compute the zvalue at the facet centres
zfacet < z[1, 1] + z[1, ncz] + z[nrz, 1] + z[nrz, ncz]
# Recode facet zvalues into color indices
facetcol < cut(zfacet, nbcol)
persp(x, y, z, col = color[facetcol], phi = 30, theta = 30)
par(op)

Questions? Problems? Suggestions? Tweet to @rdrrHQ or email at ian@mutexlabs.com.
Please suggest features or report bugs with the GitHub issue tracker.
All documentation is copyright its authors; we didn't write any of that.