#### parallelCoord.R : parallel coordinate plot ## Jonathan Rougier ## create a parallel coordinate plot where the user can specify the ## colouring of the objects. There is a similar function in the MASS ## library, parcoord parallelCoord <- function(X, col = "black", labels = colnames(X), lab.side = c("bottom", "top", "none"), lab.pos = NA) { lab.side <- match.arg(lab.side) X <- as.matrix(X) stopifnot(is.numeric(X)) p <- ncol(X) labels # force evaluations of labels pp <- tapply(X, col(X), pretty, min.n = 3, eps.correct = 1, simplify = FALSE) rng <- sapply(pp, range) mins <- rng[1, ] scales <- rng[2, ] - rng[1, ] X <- (t(X) - mins) / scales # transposed, as used in matlines plot.new() plot.window(xlim = c(1, p), ylim = c(0, 1)) for (j in 1:p) { axis.labels <- pp[[j]] axis(2, at = (axis.labels - mins[j]) / scales[j], labels = axis.labels, pos = j, lwd = 2, las = 1, xpd = NA) } matlines(1:p, X, lty = 1, pch = NA, col = col) if (!is.null(labels) && lab.side != "none") axis(switch(lab.side, bottom = 1, top = 3), at = 1:p, labels = labels, tick = FALSE, pos = lab.pos) invisible() } ## little example using the iris dataset. This dataset is available ## in R as iris, but I'm loading it from a webpage here to show how ## this is done, and how names and factor levels are assigned if (FALSE) { iris <- read.table("http://www.maths.leeds.ac.uk/~charles/mva-data/iris.dat",header = TRUE) names(iris) <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species") spnms <- c("setosa", "versicolour", "virginica") iris$Species <- factor(spnms[iris$Species], spnms) parallelCoord(iris[, 1:4], col = as.numeric(iris$Species) + 1) ## Can soup this up a bit oo <- c(2, 1, 4, 3) parallelCoord(iris[, oo], col = as.numeric(iris$Species) + 1, labels = gsub("\\.", " ", names(iris)[oo])) title(main = "Parallel coordinate plot, Fisher's Iris data") legend(1, -0.15, paste(levels(iris$Species), " "), col = seq(along = levels(iris$Species)) + 1, lty = 1, lwd = 2, pch = NA, bty = "n", horiz = TRUE, xpd = NA) }