trilinplot<-function(data, box = F, abbrv.name=F, vertex=dimnames(data)[[2]], item=dimnames(data)[[1]], ...) { # ------------------------------------------------------------------ # Produces trilinear plot. # copyright 2002 by # Mu Zhu # University of Waterloo # Waterloo, Ontario, N2L 3G1 # Canada # # references: # Allen, T. (2002), "Using and Interpreting the Trilinear Plot", # Chance 15(3), 29-35. # ------------------------------------------------------------------ if (is.null(vertex)) vertex<-c("A", "B", "C") if (is.null(item)) item<-1:nrow(data) if (abbrv.name) item <- abbreviate(item) # offset to make text position appear prettier eta <- 0.08 # vertex position anchor <- diag(3) # projection directions onto 2-d alpha1 <- c(1, -1, 0)/sqrt(2) alpha2 <- c(-0.5, -0.5, 1)/sqrt(1.5) # plot the triangle vert.x <- anchor %*% alpha1 vert.y <- anchor %*% alpha2 plot(vert.x, vert.y, type="p", xlab="", ylab="", xlim = range(vert.x)+2*c(-eta, eta), ylim = range(vert.y)+2*c(-eta, eta), axes=F, ...) if (box) box() polygon(vert.x, vert.y) offset.x <- c(eta, -eta, 0) offset.y <- c(-eta,-eta,eta) text(vert.x+offset.x, vert.y+offset.y, as.character(vertex)) # make sure each observation contains proper percentage rowsum <- as.vector(as.matrix(data) %*% rep(1,3)) data <- data/rowsum # item position pts.x <- as.matrix(data) %*% alpha1 pts.y <- as.matrix(data) %*% alpha2 # plot items onto triangle n <- nrow(data) points(pts.x, pts.y) offset.x <- eta/2*sample(c(-1, 1), size=n, replace=T) offset.y <- eta/2*sample(c(-1, 1), size=n, replace=T) text(pts.x+offset.x, pts.y+offset.y, as.character(item), cex=0.62) }