crumb

Plotting simplexes using R

In evolutionary game theory and related fields, one often needs to visualize the dynamics of three-dimensional systems, e.g. competition between three strategies $x_1$, $x_2$ and $x_3$ for which $x_1 + x_2 + x_3 = 1$. This is most conveniently done on a 2-simplex (ternary plot, de Finetti diagram), and the following code snippet defines a minimal way of visualizing data on a 2-simplex using R base graphics.

The function takes a minimum of four arguments: x and y are vectors holding the $x_1$ and $x_2$ values (it is not necessary to input the remaining, third value, as $x_3 = 1 - x_1 - x_2$); label is a vector of length 3 giving labels for the vertices of the simplex. Additional standard graphical parameters can be specified, e.g.

simplex(x=c(0.1,0.2,0.3), y=c(0.3,0.2,0.1), type="l", lwd=2, col="red")

will request a line plot with line width 2 and a red colour.

Here’s the function definition itself:

simplex <- function(x,
                    y,
                    label = expression(italic(x)[1], italic(x)[2], italic(x)[3]),
                    ...) {
  # empty plot
  op <- par(mar=c(1,0,0,0) + 0.1, pty="s")
  plot(x=c(-0.2,1.2), y=c(-0.2,1.2), type="n", axes=FALSE, xlab="", ylab="")

  # triangle (borders)
  points(x=c(0,0.5,1,0), y=c(0,0.5*sqrt(3),0,0), type="l")

  # transform the points
  xx <- 0.5*(1-x+y)
  yy <- 0.5*sqrt(3)*(1-x-y)

  # plot points
  points(x=xx, y=yy, ...)

  # labels
  if (!is.null(label)) {
    text(x=0.5, y=0.5*sqrt(3), pos=3, labels=label[3])
    text(x=0.0, y=0.0, pos=2, labels=label[1])
    text(x=1.0, y=0.0, pos=4, labels=label[2])
  }
  
  # restore plotting parameters
  par(op)
}

This minimal procedure can easily be extended in the obvious ways, as in the following state diagram with vector field:

Vector field on simplex