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.
Value
Function scatter3D returns the viewing transformation matrix.
See trans3D.
Note
For scatter2D and scatter3D the plottypes that are supported
are: type = "p", type = "l", type = "h",
type = "o". For type = "b", type = "o" is used instead.
Author(s)
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
# 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),
data = rep(0.05, 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),
data = rep(0.05, 2*length(x))),
z = matrix(nrow = length(x),
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"))
# 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), data = c(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), data = c(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)