[6531] in s-news-athena

home help back first fref pref prev next nref lref last post

Summary: contours in triangles

daemon@ATHENA.MIT.EDU (MARCEL.BAUMGARTNER@01.CHLSNR.nestr)
Tue Feb 28 04:41:57 1995

Date: Tue, 28 Feb 1995 10:21:08 +0100
From: MARCEL.BAUMGARTNER@01.CHLSNR.nestrd.ch
To: s-news@utstat.toronto.edu


------------------------------ Start of body part 1


------------------------------ Start of body part 2

Hi,

some days ago I posted a query regarding contour plots in
triangles, especially useful when displaying results of ternary
mixture designs.

Thanks to everybody who replied. I think there is a need for some
routines for doing mixture analysis. I was told that not even
S+DOX includes such functions.

It turned out that writing what I need was not that difficult,
and in fact it is a very nice exercice in geometry and linear algebra.

In what follows, I include the I wrote. The functions are
very basic, a lot more can be done. Please feel free to contact me
for comments and improvements.

Marcel Baumgartner
Marcel.Baumgartner@chlsnr.nestrd.ch

*********************************************************************
***********  Plotting routines for analyzing 3-way  *****************
***********           mixture designs               *****************
*********************************************************************

Set par(pty="s") to get real equilateral triangles (and print
in portrait mode).


To plot an equilateral triangle:
================================

vertices <- matrix(c(0,0,.5,sqrt(3)/2,1,0,0,0),ncol=2,byrow)
plot(vertices,type="l",axes=F,xlab="",ylab="")

Top corner: component 1
Left corner: component 2
Right corner: component 3

To add one or several design points:
====================================

points(x%*%triangle.trans,pch=0)

where x is a design matrix (ncol=3, sum of rows = constant,
mixture values between 0 and 1) and

triangle.trans <- matrix(c(0.5,sqrt(3)/2,0,0,1,0),ncol=2,byrow=T)


To plot contours of the fitted polynomial (using, for example, lm()):
=====================================================================

Fill in the estimated coefficients in the following template
(this is not at all user-friendly, but I see no other way yet):

z.template <- function(x, y)
{
        aux <- z.trans(x, y)
        x1 <- aux$x1
        x2 <- aux$x2
        x3 <- aux$x3
       #Linear model
        b1 * x1 + b2 * x2 + b3 * x3
       #Quadratic model
#       b1 * x1 + b2 * x2 + b3 * x3 +
        b12 * x1 * x2 + b13 * x1 * x3 + b23 * x2 * x3
       #Full Cubic model
#       b1 * x1 + b2 * x2 + b3 * x3 +
#       b12 * x1 * x2 + b13 * x1 * x3 + b23 * x2 * x3 +
#       d12 * x1 * x2 * (x1 - x2) + d13 * x1 * x3 * (x1 -x3) +
#       d23 * x2 * x3 * (x2 - x3) +
#       b123 * x1 * x2 * x3
       #Special Cubic model
#       b1 * x1 + b2 * x2 + b3 * x3 +
#       b12 * x1 * x2 + b13 * x1 * x3 + b23 * x2 * x3 +
#       b123 * x1 * x2 * x3
}

where

 z.trans <- function(x, y, constant = 1)
{
        x1 <- (2 * y)/sqrt(3)
        x2 <-  - x - y/sqrt(3) + constant
        x3 <- x - y/sqrt(3)
        list(x1 = x1, x2 = x2, x3 = x3)
}

The "constant" option is useful when your components do not sum up to
1, but to a fixed constant less than 1.

The following function does the rest:

function(z, npoints = 40, ..., levels, manual = F, labels = paste("X", 1:3, sep
	 = ""))
{
#Written by Marcel Baumgartner, Marcel.Baumgartner@chlsnr.nestrd.ch
#z: a function in the format of z.template
#npoints: number of points for contours
#levels: desired levels for contour
#manual: if TRUE, then levels can be put manually using locator()
#labels: labels for mixture components
	x.con <- seq(0, 1, length = npoints)
	y.con <- seq(0, sqrt(3)/2, length = npoints)
	if(missing(levels))
		con.out <- contour(x.con, y.con, outer(x.con, y.con, z), save
			 = T, plot = F)
	else con.out <- contour(x.con, y.con, outer(x.con, y.con, z), save = T,
			plot = F, levels = levels)
	n <- length(con.out)
	par(pty = "s")
	plot(c(0.5, 0.5), type = "n", xlim = c(0, 1), ylim = c(0, 1), xlab = "",
		ylab = "", bty = "n", axes = F)
	for(i in 1:n) {
		x <- con.out[[i]]$x
		y <- con.out[[i]]$y
		test <- rep(T, length(x))
		test[y > sqrt(3)/2 | y/x > sqrt(3) | y + sqrt(3) * x > sqrt(3)] <-
			F
		lines(x[test], y[test])
		if(!manual) {
			place <- length(x[test][!is.na(x[test])])
			place <- round(median(1:place),0)
			text(x[place], y[place], names(con.out)[i])
		}
	}
	vertices <- matrix(c(0, 0, 0.5, sqrt(3)/2, 1, 0, 0, 0), ncol = 2, byrow
		 = T)
	lines(vertices)
	text(matrix(c(0.5, sqrt(3)/2 * 1.05, -0.05, -0.05, 1.05, -0.05), ncol
		 = 2, byrow = T), labels)
	if(manual) {
		cat("Put manually contour labels: \n")
		print(names(con.out))
		for(i in 1:n)
			text(locator(1), names(con.out)[i])
	}
	invisible(con.out)
}

An example (see page 50 of J. A. Cornell, "Experiments with Mixtures:
Designs, Models, and the Analysis of Mixture Data", John Wiley,
1981):

z.p _ function(x, y)
{
        aux <- z.trans(x, y)
        x1 <- aux$x1
        x2 <- aux$x2
        x3 <- aux$x3    #Linear model
#       b1 * x1 + b2 * x2 + b3 * x3     #Quadratic model
#       b1 * x1 + b2 * x2 + b3 * x3 +
#       b12 * x1 * x2 + b13 * x1 * x3 + b23 * x2 * x3   #Full Cubic model
#       b1 * x1 + b2 * x2 + b3 * x3 +
#       b12 * x1 * x2 + b13 * x1 * x3 + b23 * x2 * x3 +
#       d12 * x1 * x2 * (x1 - x2) + d13 * x1 * x3 * (x1 -x3) +
#       d23 * x2 * x3 * (x2 - x3) +
#       b123 * x1 * x2 * x3
#Special Cubic model
        1.8 * x1 + 25.4 * x2 + 28.6 * x3 - 34.8 * x1 * x2 - 48.4 * x1 * x3 -
                94.4 * x2 * x3 + 624.6 * x1 * x2 * x3
}
motif()
plot.mixture(z.p,levels=c(5,10,15,20))


Improvements to be made:

o Localisation of level labels
o Allow z to use for example coef(model) instead of manually entering
  the model coefficients





------------------------------ End of body part 2

home help back first fref pref prev next nref lref last post