Learn R Programming

plot3D (version 1.4)

Scatter plots: Colored scatter plots and text in 2-D and 3-D

Description

scatter2D and scatter3D plot a (2- or 3 dimensional) dataset with a color variable as points or lines.

text3D plot a 3-D dataset with a color variable as text labels.

points3D is shorthand for scatter3D(..., type = "p")

lines3D is shorthand for scatter3D(..., type = "l")

points2D is shorthand for scatter2D(..., type = "p")

lines2D is shorthand for scatter2D(..., type = "l")

The 2D functions are included for their side effect of having a color key.

Usage

scatter3D (x, y, z, ..., colvar = z, phi = 40, theta = 40,
           col = NULL, NAcol = "white", breaks = NULL,
           colkey = NULL, panel.first = NULL, 
           clim = NULL, clab = NULL, 
           bty = "b", CI = NULL, surf = NULL, 
           add = FALSE, plot = TRUE)
          
text3D (x, y, z, labels, ..., colvar = NULL, phi = 40, theta = 40,
        col = NULL, NAcol = "white",  breaks = NULL,
        colkey = NULL, panel.first = NULL, 
        clim = NULL, clab = NULL, 
        bty = "b", add = FALSE, plot = TRUE)

points3D (x, y, z, ...)

lines3D (x, y, z, ...)

scatter2D (x, y, ..., colvar = NULL, col = NULL, NAcol = "white", breaks = NULL, colkey = NULL, clim = NULL, clab = NULL, CI = NULL, add = FALSE, plot = TRUE)

lines2D(x, y, ...)

points2D(x, y, ...)

text2D (x, y, labels, ..., colvar = NULL, col = NULL, NAcol = "white", breaks = NULL, colkey = NULL, clim = NULL, clab = NULL, add = FALSE, plot = TRUE)

Value

Function scatter3D returns the viewing transformation matrix. See trans3D.

Arguments

x, y, z

Vectors with x, y and z-values of the points to be plotted. They should be of equal length, and the same length as colvar (if present).

colvar

The variable used for coloring. For scatter3D, it need not be present, but if specified, it should be a vector of equal length as (x, y, z).

theta, phi

the angles defining the viewing direction. theta gives the azimuthal direction and phi the colatitude. see persp.

col

Color palette to be used for coloring the colvar variable. If col is NULL and colvar is specified, then a red-yellow-blue colorscheme (jet.col) will be used. If col is NULL and colvar is not specified, then col will be "black".

NAcol

Colors to be used for colvar values that are NA.

breaks

a set of finite numeric breakpoints for the colors; must have one more breakpoint than color and be in increasing order. Unsorted vectors will be sorted, with a warning.

colkey

A logical, NULL (default), or a list with parameters for the color key (legend). List parameters should be one of side, plot, length, width, dist, shift, addlines, col.clab, cex.clab, side.clab, line.clab, adj.clab, font.clab and the axis parameters at, labels, tick, line, pos, outer, font, lty, lwd, lwd.ticks, col.box, col.axis, col.ticks, hadj, padj, cex.axis, mgp, tck, tcl, las. The defaults for the parameters are side = 4, plot = TRUE, length = 1, width = 1, dist = 0, shift = 0, addlines = FALSE, col.clab = NULL, cex.clab = par("cex.lab"), side.clab = NULL, line.clab = NULL, adj.clab = NULL, font.clab = NULL) See colkey.

The default is to draw the color key on side = 4, i.e. in the right margin. If colkey = NULL then a color key will be added only if col is a vector. Setting colkey = list(plot = FALSE) will create room for the color key without drawing it. if colkey = FALSE, no color key legend will be added.

CI

A list with parameters and values for the confidence intervals or NULL. If a list it should contain at least the item x, y or z (latter for scatter3D). These should be 2-columned matrices, defining the left/right intervals. Other parameters should be one of (with defaults): alen = 0.01, lty = par("lty"), lwd = par("lwd"), col = NULL, to set the length of the arrow head, the line type and width, and the color. If col is NULL, then the colors as specified by colvar are used. See examples.

panel.first

A function to be evaluated after the plot axes are set up but before any plotting takes place. This can be useful for drawing background grids or scatterplot smooths. The function should have as argument the transformation matrix, e.g. it should be defined as function(pmat). See example of persp3D and last example of voxel3D.

clab

Only if colkey is not NULL or FALSE, the label to be written on top of the color key. The label will be written at the same level as the main title. To lower it, clab can be made a vector, with the first values empty strings.

clim

Only if colvar is specified, the range of the color variable, used for the color key. Values of colvar that extend the range will be put to NA.

bty

The type of the box, the default draws only the back panels. Only effective if the persp argument (box) equals TRUE (this is the default). See perspbox. Note: the bty = "g", "b2", "bl" can also be specified for scatter2D (if add = FALSE).

labels

The text to be written. A vector of length equal to length of x, y, z.

surf

If not NULL, a list specifying a (fitted) surface to be added on the scatterplot. The list should include at least x, y, z, defining the surface, and optional: colvar, col, NAcol, border, facets, lwd, resfac, clim, ltheta, lphi, shade, lighting, fit. Note that the default is that colvar is not specified which will set colvar = z. The argument fit should give the fitted z-values, in the same order as the z-values of the scatter points, for instance produced by predict. When present, this will produce droplines from points to the fitted surface.

add

Logical. If TRUE, then the points will be added to the current plot. If FALSE a new plot is started.

plot

Logical. If TRUE (default), a plot is created, otherwise (for 3D plots) the viewing transformation matrix is returned (as invisible).

...

additional arguments passed to the plotting methods.

The following persp arguments can be specified: xlim, ylim, zlim, xlab, ylab, zlab, main, sub, r, d, scale, expand, box, axes, nticks, ticktype. The arguments xlim, ylim, zlim only affect the axes for 3D plots. All objects will be plotted, including those that fall out of these ranges. To select objects only within the axis limits, use plotdev.

In addition, the perspbox arguments col.axis, col.panel, lwd.panel, col.grid, lwd.grid can also be given a value.

shade and lighting arguments will have no effect.

alpha can be given a value inbetween 0 and 1 to make colors transparent.

For all functions, the arguments lty, lwd can be specified; type can be specified for all except text3D.

In case type = "p" or "b", then pch, cex, bg can also be specified.

The arguments after ... must be matched exactly.

Author

Karline Soetaert <karline.soetaert@nioz.nl>

See Also

persp for the function on which this implementation is based.

mesh, trans3D, slice3D, for other examples of scatter2D or scatter3D.

plotdev for zooming, rescaling, rotating a plot.

package scatterplot3D for an implementation of scatterplots that is not based on persp.

Examples

Run this code
# save plotting parameters
 pm <- par("mfrow")

 
## =======================================================================
## A sphere 
## =======================================================================

 par(mfrow = c(1, 1))
 M  <- mesh(seq(0, 2*pi, length.out = 100), 
            seq(0,   pi, length.out = 100))
 u  <- M$x ; v  <- M$y

 x <- cos(u)*sin(v)
 y <- sin(u)*sin(v)
 z <- cos(v)

# full  panels of box are drawn (bty = "f")
 scatter3D(x, y, z, pch = ".", col = "red", 
           bty = "f", cex = 2, colkey = FALSE)

## =======================================================================
## Different types
## =======================================================================

 par (mfrow = c(2, 2))
 z <- seq(0, 10, 0.2)
 x <- cos(z)
 y <- sin(z)*z

# greyish background for the boxtype (bty = "g") 
 scatter3D(x, y, z, phi = 0, bty = "g",
           pch = 20, cex = 2, ticktype = "detailed")
# add another point
 scatter3D(x = 0, y = 0, z = 0, add = TRUE, colkey = FALSE, 
           pch = 18, cex = 3, col = "black")

# add text
 text3D(x = cos(1:10), y = (sin(1:10)*(1:10) - 1), 
        z = 1:10, colkey = FALSE, add = TRUE, 
        labels = LETTERS[1:10], col = c("black", "red"))

# line plot
 scatter3D(x, y, z, phi = 0, bty = "g", type = "l", 
           ticktype = "detailed", lwd = 4)

# points and lines
 scatter3D(x, y, z, phi = 0, bty = "g", type = "b", 
           ticktype = "detailed", pch = 20, 
           cex = c(0.5, 1, 1.5))

# vertical lines
 scatter3D(x, y, z, phi = 0, bty = "g",  type = "h", 
           ticktype = "detailed")

## =======================================================================
## With confidence interval
## =======================================================================

 x <- runif(20)
 y <- runif(20)
 z <- runif(20)

 par(mfrow = c(1, 1))
 CI <- list(z = matrix(nrow = length(x), ncol = 2,
                       data = rep(0.05, times = 2*length(x))))

# greyish background for the boxtype (bty = "g")
 scatter3D(x, y, z, phi = 0, bty = "g", CI = CI,
   col = gg.col(100), pch = 18, cex = 2, ticktype = "detailed",
   xlim = c(0, 1), ylim = c(0, 1), zlim = c(0, 1))

# add new set of points
 x <- runif(20)
 y <- runif(20)
 z <- runif(20)

 CI2 <- list(x = matrix(nrow = length(x), ncol = 2,
                       data = rep(0.05, 2*length(x))),
             z = matrix(nrow = length(x), ncol = 2,
                       data = rep(0.05, 2*length(x))))

 scatter3D(x, y, z, CI = CI2, add = TRUE, col = "red", pch = 16)

## =======================================================================
## With a surface
## =======================================================================

 par(mfrow = c(1, 1))
 
# surface = volcano
 M <- mesh(1:nrow(volcano), 1:ncol(volcano))

# 100 points above volcano 
 N  <- 100
 xs <- runif(N) * 87
 ys <- runif(N) * 61
 zs <- runif(N)*50 + 154
  
# scatter + surface
 scatter3D(xs, ys, zs, ticktype = "detailed", pch = 16, 
   bty = "f", xlim = c(1, 87), ylim = c(1,61), zlim = c(94, 215), 
   surf = list(x = M$x, y = M$y, z = volcano,  
               NAcol = "grey", shade = 0.1))
 
## =======================================================================
## A surface and CI
## =======================================================================

 par(mfrow = c(1, 1))
 M <- mesh(seq(0, 2*pi, length = 30), (1:30)/100)
 z <- with (M, sin(x) + y)
 
# points 'sampled'
 N <- 30
 xs <- runif(N) * 2*pi
 ys <- runif(N) * 0.3

 zs <- sin(xs) + ys + rnorm(N)*0.3
 
 CI <- list(z = matrix(nrow = length(xs), 
                       data = rep(0.3, 2*length(xs))),
            lwd = 3)
  
# facets = NA makes a transparent surface; borders are black
 scatter3D(xs, ys, zs, ticktype = "detailed", pch = 16, 
   xlim = c(0, 2*pi), ylim = c(0, 0.3), zlim = c(-1.5, 1.5), 
   CI = CI, theta = 20, phi = 30, cex = 2,
   surf = list(x = M$x, y = M$y, z = z, border = "black", facets = NA)
   )

## =======================================================================
## droplines till the fitted surface
## =======================================================================

 with (mtcars, {

  # linear regression
   fit <- lm(mpg ~ wt + disp)

  # predict values on regular xy grid
   wt.pred <- seq(1.5, 5.5, length.out = 30)
   disp.pred <- seq(71, 472, length.out = 30)
   xy <- expand.grid(wt = wt.pred, 
                     disp = disp.pred)

   mpg.pred <- matrix (nrow = 30, ncol = 30, 
      data = predict(fit, newdata = data.frame(xy), 
      interval = "prediction")[,1])

# fitted points for droplines to surface
   fitpoints <- predict(fit) 

   scatter3D(z = mpg, x = wt, y = disp, pch = 18, cex = 2, 
      theta = 20, phi = 20, ticktype = "detailed",
      xlab = "wt", ylab = "disp", zlab = "mpg",  
      surf = list(x = wt.pred, y = disp.pred, z = mpg.pred,  
                  facets = NA, fit = fitpoints),
      main = "mtcars")
  
 })

## =======================================================================
## Two ways to make a scatter 3D of quakes data set
## =======================================================================

 par(mfrow = c(1, 1)) 
# first way, use vertical spikes (type = "h")
 with(quakes, scatter3D(x = long, y = lat, z = -depth, colvar = mag, 
      pch = 16, cex = 1.5, xlab = "longitude", ylab = "latitude", 
      zlab = "depth, km", clab = c("Richter","Magnitude"),
      main = "Earthquakes off Fiji", ticktype = "detailed", 
      type = "h", theta = 10, d = 2, 
      colkey = list(length = 0.5, width = 0.5, cex.clab = 0.75))
      )

# second way: add dots on bottom and left panel
# before the scatters are drawn, 
# add small dots on basal plane and on the depth plane
 panelfirst <- function(pmat) {
    zmin <- min(-quakes$depth)
    XY <- trans3D(quakes$long, quakes$lat, 
                  z = rep(zmin, nrow(quakes)), pmat = pmat)
    scatter2D(XY$x, XY$y, colvar = quakes$mag, pch = ".", 
            cex = 2, add = TRUE, colkey = FALSE)
 
    xmin <- min(quakes$long)
    XY <- trans3D(x = rep(xmin, nrow(quakes)), y = quakes$lat, 
                  z = -quakes$depth, pmat = pmat)
    scatter2D(XY$x, XY$y, colvar = quakes$mag, pch = ".", 
            cex = 2, add = TRUE, colkey = FALSE)
 }

 with(quakes, scatter3D(x = long, y = lat, z = -depth, colvar = mag, 
      pch = 16, cex = 1.5, xlab = "longitude", ylab = "latitude", 
      zlab = "depth, km", clab = c("Richter","Magnitude"),
      main = "Earthquakes off Fiji", ticktype = "detailed", 
      panel.first = panelfirst, theta = 10, d = 2, 
      colkey = list(length = 0.5, width = 0.5, cex.clab = 0.75))
      )

## =======================================================================
## text3D and scatter3D
## =======================================================================

 with(USArrests, text3D(Murder, Assault, Rape, 
    colvar = UrbanPop, col = gg.col(100), theta = 60, phi = 20,
    xlab = "Murder", ylab = "Assault", zlab = "Rape", 
    main = "USA arrests", 
    labels = rownames(USArrests), cex = 0.6, 
    bty = "g", ticktype = "detailed", d = 2,
    clab = c("Urban","Pop"), adj = 0.5, font = 2))

 with(USArrests, scatter3D(Murder, Assault, Rape - 1, 
    colvar = UrbanPop, col = gg.col(100), 
    type = "h", pch = ".", add = TRUE))

## =======================================================================
## zoom near origin
## =======================================================================

# display axis ranges
 getplist()[c("xlim","ylim","zlim")] 

# choose suitable ranges
 plotdev(xlim = c(0, 10), ylim = c(40, 150), 
         zlim = c(7, 25))

## =======================================================================
## text3D to label x- and y axis
## =======================================================================

 par(mfrow = c(1, 1))
 hist3D (x = 1:5, y = 1:4, z = VADeaths,
        bty = "g", phi = 20,  theta = -60,
        xlab = "", ylab = "", zlab = "", main = "VADeaths",
        col = "#0072B2", border = "black", shade = 0.8,
        ticktype = "detailed", space = 0.15, d = 2, cex.axis = 1e-9)

 text3D(x = 1:5, y = rep(0.5, 5), z = rep(3, 5),
       labels = rownames(VADeaths),
       add = TRUE, adj = 0)
 text3D(x = rep(1, 4),   y = 1:4, z = rep(0, 4),
       labels  = colnames(VADeaths),
       add = TRUE, adj = 1)

## =======================================================================
## Scatter2D; bty can also be set = to one of the perspbox alernatives
## =======================================================================

 par(mfrow = c(2, 2))
 x <- seq(0, 2*pi, length.out = 30)

 scatter2D(x, sin(x), colvar = cos(x), pch = 16, 
         ylab = "sin", clab = "cos", cex = 1.5)
# other box types:
 scatter2D(x, sin(x), colvar = cos(x), type = "l", lwd = 4, bty = "g")
 scatter2D(x, sin(x), colvar = cos(x), type = "b", lwd = 2, bty = "b2")
# transparent colors and spikes
 scatter2D(x, sin(x), colvar = cos(x), type = "h", lwd = 4, alpha = 0.5)
  
## =======================================================================
## mesh examples and scatter2D
## =======================================================================

 par(mfrow = c(1, 2))
 x <- seq(-1, 1, by = 0.1)
 y <- seq(-2, 2, by = 0.2)

 grid <- mesh(x, y)
 z    <- with(grid, cos(x) * sin(y))
 image2D(z, x = x, y = y)
 points(grid)
 scatter2D(grid$x, grid$y, colvar = z, pch = 20, cex = 2)

## =======================================================================
## scatter plot with confidence intervals
## =======================================================================

 par(mfrow = c(2, 2))
 x  <- sort(rnorm(10)) 
 y  <- runif(10)
 cv <- sqrt(x^2 + y^2)

 CI <- list(lwd = 2)
 CI$x <- matrix (nrow = length(x), ncol = 2, data = rep(0.25, 2*length(x)))
 scatter2D(x, y, colvar = cv, pch = 16, cex = 2, CI = CI)
 scatter2D(x, y, colvar = cv, pch = 16, cex = 2, CI = CI, type = "b")

 CI$y <- matrix (nrow = length(x), ncol = 2, data = rep(0.05, 2*length(x)))
 CI$col <- "black"
 scatter2D(x, y, colvar = cv, pch = 16, cex = 2, CI = CI)

 CI$y[c(2,4,8,10), ] <- NA  # Some points have no CI
 CI$x[c(2,4,8,10), ] <- NA  # Some points have no CI
 CI$alen <- 0.02            # increase arrow head
 scatter2D(x, y, colvar = cv, pch = 16, cex = 2, CI = CI)

## =======================================================================
## Scatter on an image
## =======================================================================
 
 par(mfrow = c(1, 1))
# image of oxygen saturation
 oxlim <- range(Oxsat$val[,,1], na.rm  = TRUE) 
 image2D(z = Oxsat$val[,,1], x = Oxsat$lon, y = Oxsat$lat,
       contour = TRUE, 
       xlab = "longitude", ylab = "latitude", 
       main = "Oxygen saturation", clim = oxlim, clab = "%")

# (imaginary) measurements at 5 sites
 lon   <- c( 11.2,   6.0, 0.9,  -4, -8.8)
 lat   <- c(-19.7,-14.45,-9.1,-3.8, -1.5)
 O2sat <- c(   90,    95,  92,  85,  100)
               
# add to image; use same zrange; avoid adding  a color key
 scatter2D(colvar = O2sat, x = lon, y = lat, clim = oxlim, pch = 16,
         add = TRUE, cex = 2, colkey = FALSE)

## =======================================================================
## Scatter on a contourplot
## =======================================================================

 par(mfrow = c(1, 1))

# room for colorkey by setting colkey = list(plot = FALSE)

# contour plot of the ocean's bathymetry
 Depth <- Hypsometry$z
 Depth[Depth > 0] <- NA
 contour2D(z = Depth, x = Hypsometry$x, y = Hypsometry$y, 
       xlab = "longitude", ylab = "latitude", 
       col = "black", NAcol = "grey", levels = seq(-6000, 0, by = 2000),
       main = "Oxygen saturation along ship track", 
       colkey = list(plot = FALSE))

# add data to image; with  a color key
 scatter2D(colvar = O2sat, x = lon, y = lat, pch = 16,
         add = TRUE, cex = 2, clab = "%")

## =======================================================================
## scatter2D for time-series plots
## =======================================================================

# Plotting sunspot 'anomalies'
sunspot <- data.frame(year = time(sunspot.month), 
  anom = sunspot.month - mean(sunspot.month))

# long-term moving average of anomaly
ff <- 100
sunspot$ma <- filter(sunspot$anom, rep(1/ff, ff), sides = 2)

with (sunspot, lines2D(year, anom, 
  colvar = anom > 0, 
  col = c("pink", "lightblue"),
  main = "sunspot anomaly", type = "h", 
  colkey = FALSE, las = 1, xlab = "year", ylab = ""))
lines2D(sunspot$year, sunspot$ma, add = TRUE)  

# The same
#with (sunspot, plot(year, anom, 
#  col = c("pink", "lightblue")[(anom > 0) + 1],
#  main = "sunspot", type = "h", las = 1))

# but this does not work due to NAs...  
# lines(sunspot$year, sunspot$ma)  

## =======================================================================
## text2D
## =======================================================================

 with(USArrests, text2D(x = Murder, y = Assault + 5, colvar = Rape, 
     xlab = "Murder", ylab = "Assault", clab = "Rape", 
     main = "USA arrests", labels = rownames(USArrests), cex = 0.6, 
     adj = 0.5, font = 2))

 with(USArrests, scatter2D(x = Murder, y = Assault, colvar = Rape, 
     pch = 16, add = TRUE, colkey = FALSE))

# reset plotting parameters
 par(mfrow = pm)

Run the code above in your browser using DataLab