Author: Martin R. Smith
Date: 2026-02-03

# Adding annotations

#### Martin R. Smith

#### 2026-02-03

> Before you start, have you read the introduction to the Ternary package?

This vignette explores how to annotate specific points within a ternary plot. We’ll start by generating some example data:

    set.seed(40) # For reproducibility

    nPoints <- 40
    points <- data.frame(
      a = abs(rnorm(nPoints, 2, 3)),
      b = abs(rnorm(nPoints, 1, 1.5)),
      c = abs(rnorm(nPoints, 1, 0.5)),
      col = sample(2:5, nPoints, replace = TRUE),
      label = paste("Point", seq_len(nPoints))
    )

It’s simple to plot and annotate all points with automatically positioned labels:

    library("Ternary") # Load the Ternary package

    # Create ternary plot
    par(mar = rep(0.2, 4)) # Set figure margins
    TernaryPlot("a", "b", "c")

    # Add points
    TernaryPoints(points[, 1:3], col = points[, "col"], pch = 16)

    # Add annotations automatically
    Annotate(points[, 1:3], col = points[, "col"])

If we want more control than the `Annotate()` function permits, we can manually select which points to annotate and where to place their labels.

    # Create ternary plot
    par(mar = rep(0.2, 4)) # Set figure margins
    TernaryPlot("a", "b", "c")

    # Add points
    TernaryPoints(points[, 1:3], col = points[, "col"], pch = 16)

    # Choose points to label
    toLabel <- c(10, 20, 30, 40)

    # Get Cartesian coordinates of points
    # Note that we need to rotate the data.frame with `t()`
    pointXY <- TernaryToXY(t(points[toLabel, c("a", "b", "c")]))

    # We will manually specify where we want to position our labels.
    # It can help to establish the coordinates of the figure region:
    par("usr") # c(x1, x2, y1, y2)

    ## [1] -0.6264000  0.6264000 -0.1933873  1.0594127

    # And the X and Y range of the ternary plot itself:
    TernaryXRange()

    ## [1] -0.5  0.5

    TernaryYRange()

    ## [1] -0.0669873  0.9330127

    # Manually select locations for labels:
    labelXY <- rbind(c(0.28, 0.7),
                     c(0.35, 0.6),
                     c(0.42, 0.5),
                     c(0.49, 0.4))[c(3, 4, 1, 2), ]

    # Add labels to plot
    text(labelXY,
         labels = points[toLabel, "label"],
         col = points[toLabel, "col"],
         pos = 4, # Place text to right of coordinate
         xpd = NA # Don't clip at figure limit
         )

    # Connect labels to points
    segments(
      pointXY["x", ], pointXY["y", ],
      labelXY[, 1], labelXY[, 2],
      lwd = 2, # Line width
      col = points[toLabel, "col"]
    )

# Where next

For other examples of usage, see the accompanying vignettes:

- Introduction for new R users

- Getting started guide

- Interpolating and contouring

- Plotting Holdridge climate zones