| plotmath {base} | R Documentation | 
If the text argument to one of the text-drawing functions
(text, mtext, axis) in R
is an expression, the argument is interpreted as a mathematical
expression and the output will be formatted according to TeX-like
rules.
A mathematical expression must obey the normal rules of syntax for any R expression, but it is interpreted according to very different rules than for normal R expressions.
It is possible to produce many different mathematical symbols, generate sub- or superscripts, produce fractions, etc.
The output from example(plotmath) includes several tables which
show the available features.  In these tables, the columns of grey text
show sample R expressions, and the columns of black text show the
resulting output.  
The available features are also described in the tables below:
| Syntax | Meaning | 
 x + y    |   x plus y | 
 x - y    |   x minus y | 
 x*y     |   juxtapose x and y | 
 x/y     |   x forwardslash y | 
 x %+-% y    |   x plus or minus y | 
 x %/% y    |   x divided by y | 
 x %*% y    |   x times y | 
 x[i]    |   x subscript i | 
 x^2     |   x superscript 2 | 
 paste(x, y, z)  |   juxtapose x, y, and z | 
 sqrt(x)    |   square root of x | 
 sqrt(x, y)    |   yth root of x | 
 x == y    |   x equals y | 
 x != y    |   x is not equal to y | 
 x < y    |   x is less than y | 
 x <= y    |   x is less than or equal to y | 
 x > y    |   x is greater than y | 
 x >= y    |   x is greater than or equal to y | 
 x %~~% y    |   x is approximately equal to y | 
 x %=~% y    |   x and y are congruent | 
 x %==% y    |   x is defined as y | 
 x %prop% y   |   x is proportional to y | 
 plain(x)    |   draw x in normal font | 
 bold(x)    |   draw x in bold font | 
 italic(x)    |   draw x in italic font | 
 bolditalic(x)  |   draw x in bolditalic font | 
 list(x, y, z)  |   comma-separated list | 
 ...     |   ellipsis (height varies) | 
 cdots    |   ellipsis (vertically centred) | 
 ldots    |   ellipsis (at baseline) | 
 x %subset% y  |   x is a proper subset of y | 
 x %subseteq% y  |   x is a subset of y | 
 x %notsubset% y  |   x is not a subset of y | 
 x %supset% y  |   x is a proper superset of y | 
 x %supseteq% y  |   x is a superset of y | 
 x %in% y    |   x is an element of y | 
 x %notin% y  |   x is not an element of y | 
 hat(x)    |   x with a circumflex | 
 tilde(x)    |   x with a tilde | 
 ring(x)    |   x with a ring | 
 bar(xy)    |   xy with bar | 
 widehat(xy)    |   xy with a wide circumflex | 
 widetilde(xy)  |   xy with a wide tilde | 
 x %<->% y    |   x double-arrow y | 
 x %->% y    |   x right-arrow y | 
 x %<-% y    |   x left-arrow y | 
 x %up% y    |   x up-arrow y | 
 x %down% y   |   x down-arrow y | 
 x %<=>% y    |   x is equivalent to y | 
 x %=>% y    |   x implies y | 
 x %<=% y    |   y implies x | 
 x %dblup% y    |   x double-up-arrow y | 
 x %dbldown% y  |   x double-down-arrow y | 
 alpha  omega  |   Greek symbols | 
 Alpha  Omega  |   uppercase Greek symbols | 
 infinity    |   infinity symbol | 
 32*degree    |   32 degrees | 
 60*minute    |   60 minutes of angle | 
 30*second    |   30 seconds of angle | 
 displaystyle(x)  |   draw x in normal size (extra spacing) | 
 textstyle(x)   |   draw x in normal size | 
 scriptstyle(x)  |   draw x in small size | 
 scriptscriptstyle(x)  |   draw x in very small size | 
 x ~~ y         |   put extra space between x and y | 
 x + phantom(0) + y  |   leave gap for "0", but don't draw it | 
 x + over(1, phantom(0))  |   leave vertical gap for "0" (don't draw) | 
 frac(x, y)    |   x over y | 
 over(x, y)    |   x over y | 
 atop(x, y)    |   x over y (no horizontal bar) | 
 sum(x[i], i==1, n)  |   sum x[i] for i equals 1 to n | 
 prod(plain(P)(X==x), x)  |   product of P(X=x) for all values of x | 
 integral(f(x)*dx, a, b)  |   definite integral of f(x) wrt x | 
 union(A[i], i==1, n)  |   union of A[i] for i equals 1 to n | 
 intersect(A[i], i==1, n)  |   intersection of A[i] | 
 lim(f(x), x %->% 0)  |   limit of f(x) as x tends to 0 | 
 min(g(x), x > 0)  |   minimum of g(x) for x greater than 0 | 
 inf(S)         |   infimum of S | 
 sup(S)    |   supremum of S | 
 x^y + z    |   normal operator precedence | 
 x^(y + z)     |   visible grouping of operands | 
 x^{y + z}   |   invisible grouping of operands | 
 group("(",list(a, b),"]")  |   specify left and right delimiters | 
 bgroup("(",atop(x,y),")")  |   use scalable delimiters | 
 group(lceil, x, rceil)  |   special delimiters | 
Murrell, P. and Ihaka, R. (2000) An approach to providing mathematical annotation in plots. Journal of Computational and Graphical Statistics (In press).
x <- seq(-4, 4, len = 101)
y <- cbind(sin(x), cos(x))
matplot(x, y, type = "l", xaxt = "n",
        main = expression(paste(plain(sin) * phi, "  and  ",
                                plain(cos) * phi)),
        ylab = expression("sin" * phi, "cos" * phi), # only 1st is taken
        xlab = expression(paste("Phase Angle ", phi)),
        col.main = "blue")
axis(1, at = c(-pi, -pi/2, 0, pi/2, pi),
     lab = expression(-pi, -pi/2, 0, pi/2, pi))
plot(1:10, 1:10)
text(4, 9, expression(hat(beta) == (X^t * X)^{-1} * X^t * y))
text(4, 8.4, "expression(hat(beta) == (X^t * X)^{-1} * X^t * y)",
     cex = .8)
text(4, 7, expression(bar(x) == sum(frac(x[i], n), i==1, n)))
text(4, 6.4, "expression(bar(x) == sum(frac(x[i], n), i==1, n))",
     cex = .8)
text(8, 5, expression(paste(frac(1, sigma*sqrt(2*pi)), " ",
                            plain(e)^{frac(-(x-mu)^2, 2*sigma^2)})),
     cex= 1.2)
######
# create tables of mathematical annotation functionality
######
make.table <- function(nr, nc) {
    savepar <- par(mar=rep(0, 4), pty="s")
    plot(c(0, nc*2 + 1), c(0, -(nr + 1)), 
         type="n", xlab="", ylab="", axes=F)
    savepar
}
get.r <- function(i, nr) {
    i %% nr + 1
}
get.c <- function(i, nr) {
    i %/% nr + 1
}
draw.title.cell <- function(title, i, nr) {
    r <- get.r(i, nr)
    c <- get.c(i, nr)
    text(2*c - .5, -r, title)
    rect((2*(c - 1) + .5), -(r - .5), (2*c + .5), -(r + .5))
}
draw.plotmath.cell <- function(expr, i, nr, string = NULL) {
    r <- get.r(i, nr)
    c <- get.c(i, nr)
    if (is.null(string)) {
        string <- deparse(expr)
        string <- substr(string, 12, nchar(string) - 1)
    }
    text((2*(c - 1) + 1), -r, string, col="grey")
    text((2*c), -r, expr, adj=c(.5,.5))
    rect((2*(c - 1) + .5), -(r - .5), (2*c + .5), -(r + .5), border="grey")
}
nr <- 20
nc <- 2
oldpar <- make.table(nr, nc)
i <- 0
draw.title.cell("Arithmetic Operators", i, nr); i <- i + 1
draw.plotmath.cell(expression(x + y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x - y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x * y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x / y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %+-% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %/% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %*% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(-x), i, nr); i <- i + 1
draw.plotmath.cell(expression(+x), i, nr); i <- i + 1
draw.title.cell("Sub/Superscripts", i, nr); i <- i + 1
draw.plotmath.cell(expression(x[i]), i, nr); i <- i + 1
draw.plotmath.cell(expression(x^2), i, nr); i <- i + 1
draw.title.cell("Juxtaposition", i, nr); i <- i + 1
draw.plotmath.cell(expression(x * y), i, nr); i <- i + 1
draw.plotmath.cell(expression(paste(x, y, z)), i, nr); i <- i + 1
draw.title.cell("Lists", i, nr); i <- i + 1
draw.plotmath.cell(expression(list(x, y, z)), i, nr); i <- i + 1
# even columns up
i <- 20
draw.title.cell("Radicals", i, nr); i <- i + 1
draw.plotmath.cell(expression(sqrt(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(sqrt(x, y)), i, nr); i <- i + 1
draw.title.cell("Relations", i, nr); i <- i + 1
draw.plotmath.cell(expression(x == y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x != y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x < y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x <= y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x > y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x >= y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %~~% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %=~% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %==% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %prop% y), i, nr); i <- i + 1
draw.title.cell("Typeface", i, nr); i <- i + 1
draw.plotmath.cell(expression(plain(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(italic(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(bold(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(bolditalic(x)), i, nr); i <- i + 1
# Need fewer, wider columns for ellipsis ...
nr <- 20
nc <- 2
make.table(nr, nc)
i <- 0
draw.title.cell("Ellipsis", i, nr); i <- i + 1
draw.plotmath.cell(expression(list(x[1], ..., x[n])), i, nr); i <- i + 1
draw.plotmath.cell(expression(x[1] + ... + x[n]), i, nr); i <- i + 1
draw.plotmath.cell(expression(list(x[1], cdots, x[n])), i, nr); i <- i + 1
draw.plotmath.cell(expression(x[1] + ldots + x[n]), i, nr); i <- i + 1
draw.title.cell("Set Relations", i, nr); i <- i + 1
draw.plotmath.cell(expression(x %subset% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %subseteq% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %supset% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %supseteq% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %notsubset% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %in% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %notin% y), i, nr); i <- i + 1
draw.title.cell("Accents", i, nr); i <- i + 1
draw.plotmath.cell(expression(hat(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(tilde(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(ring(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(bar(xy)), i, nr); i <- i + 1
draw.plotmath.cell(expression(widehat(xy)), i, nr); i <- i + 1
draw.plotmath.cell(expression(widetilde(xy)), i, nr); i <- i + 1
draw.title.cell("Arrows", i, nr); i <- i + 1
draw.plotmath.cell(expression(x %<->% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %->% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %<-% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %up% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %down% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %<=>% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %=>% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %<=% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %dblup% y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x %dbldown% y), i, nr); i <- i + 1
draw.title.cell("Symbolic Names", i, nr); i <- i + 1
draw.plotmath.cell(expression(Alpha - Omega), i, nr); i <- i + 1
draw.plotmath.cell(expression(alpha - omega), i, nr); i <- i + 1
draw.plotmath.cell(expression(infinity), i, nr); i <- i + 1
draw.plotmath.cell(expression(32 * degree), i, nr); i <- i + 1
draw.plotmath.cell(expression(60 * minute), i, nr); i <- i + 1
draw.plotmath.cell(expression(30 * second), i, nr); i <- i + 1
# Need even fewer, wider columns for typeface and style ...
nr <- 20
nc <- 1
make.table(nr, nc)
i <- 0
draw.title.cell("Style", i, nr); i <- i + 1
draw.plotmath.cell(expression(displaystyle(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(textstyle(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(scriptstyle(x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(scriptscriptstyle(x)), i, nr); i <- i + 1
draw.title.cell("Spacing", i, nr); i <- i + 1
draw.plotmath.cell(expression(x ~~ y), i, nr); i <- i + 1
# Need fewer, taller rows for fractions ...
# cheat a bit to save pages
par(new =T)
nr <- 10
nc <- 1
make.table(nr, nc)
i <- 4
draw.plotmath.cell(expression(x + phantom(0) + y), i, nr); i <- i + 1
draw.plotmath.cell(expression(x + over(1, phantom(0))), i, nr); i <- i + 1
draw.title.cell("Fractions", i, nr); i <- i + 1
draw.plotmath.cell(expression(frac(x, y)), i, nr); i <- i + 1
draw.plotmath.cell(expression(over(x, y)), i, nr); i <- i + 1
draw.plotmath.cell(expression(atop(x, y)), i, nr); i <- i + 1
# Need fewer, taller rows and fewer, wider columns for big operators ...
nr <- 10
nc <- 1
make.table(nr, nc)
i <- 0
draw.title.cell("Big Operators", i, nr); i <- i + 1
draw.plotmath.cell(expression(sum(x[i], i=1, n)), i, nr); i <- i + 1
draw.plotmath.cell(expression(prod(plain(P)(X == x), x)), i, nr); i <- i + 1
draw.plotmath.cell(expression(integral(f(x) * dx, a, b)), i, nr); i <- i + 1
draw.plotmath.cell(expression(union(A[i], i==1, n)), i, nr); i <- i + 1
draw.plotmath.cell(expression(intersect(A[i], i==1, n)), i, nr); i <- i + 1
draw.plotmath.cell(expression(lim(f(x), x %->% 0)), i, nr); i <- i + 1
draw.plotmath.cell(expression(min(g(x), x >= 0)), i, nr); i <- i + 1
draw.plotmath.cell(expression(inf(S)), i, nr); i <- i + 1
draw.plotmath.cell(expression(sup(S)), i, nr); i <- i + 1
make.table(nr, nc)
i <- 0
draw.title.cell("Grouping", i, nr); i <- i + 1
draw.plotmath.cell(expression((x + y)*z), i, nr); i <- i + 1
draw.plotmath.cell(expression(x^y + z), i, nr); i <- i + 1
draw.plotmath.cell(expression(x^(y + z)), i, nr); i <- i + 1
# have to do this one by hand
draw.plotmath.cell(expression(x^{y + z}), i, nr, string="x^{y + z}"); i <- i + 1
draw.plotmath.cell(expression(group("(", list(a, b), "]")), i, nr); i <- i + 1
draw.plotmath.cell(expression(bgroup("(", atop(x, y), ")")), i, nr); i <- i + 1
draw.plotmath.cell(expression(group(lceil, x, rceil)), i, nr); i <- i + 1
draw.plotmath.cell(expression(group(lfloor, x, rfloor)), i, nr); i <- i + 1
draw.plotmath.cell(expression(group("|", x, "|")), i, nr); i <- i + 1
par(oldpar)