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 x1, x2 and x3 for which x1 + x2 + x3 = 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 x1 and x2 values (it is not necessary to input the remaining, third value, as x3 = 1 - x1 - x2); 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,
                    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

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

Vector field on simplex