--- title: "Using LaTeX Math in ggplot2" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Using LaTeX Math in ggplot2} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 4, dpi = 300, dev = "png" ) library(gridmicrotex) library(ggplot2) ``` ## `geom_latex()` and `element_latex()` `geom_latex()` works like `geom_text()`, with LaTeX labels. The `size` aesthetic is the font size in points. `element_latex()` renders a theme element, such as an axis title, as LaTeX. ```{r geom-basic, out.width="70%"} df <- data.frame( x = 1:3, y = 1:3, eq = c(r"($x^2$)", r"(\frac{a}{b})", r"($\sum_{i=1}^n x_i$)"), col = c("red", "blue", "green") ) ggplot(df, aes(x, y, label = eq, colour = col, size = c(14, 18, 14))) + geom_latex() + scale_colour_identity() + scale_size_identity() + labs( x = r"($\beta_1 \cdot x + \beta_0$)", y = r"($\mathrm{mpg}$)" ) + theme( axis.title.x = element_latex(fontsize = 14), axis.title.y = element_latex(fontsize = 14) ) ``` The `$` signs are optional here: `\frac{a}{b}` and `$\frac{a}{b}$` give the same result. ### Annotations `annotate("latex", ...)` adds a single label: ```{r regression-annotation, out.width="70%"} fit <- lm(mpg ~ wt, data = mtcars) b0 <- round(coef(fit)[1], 1) b1 <- round(coef(fit)[2], 1) r2 <- round(summary(fit)$r.squared, 3) eq_label <- sprintf(r"($\hat{y} = %s %s x, \quad R^2 = %s$)", b0, b1, r2) ggplot(mtcars, aes(wt, mpg)) + geom_point() + geom_smooth(method = "lm", se = FALSE) + annotate("latex", x = 4, y = 30, label = eq_label, size = 12) + theme_minimal() ``` ## Without new functions With `latex_options(device_math = TRUE)`, ordinary `geom_text()` and `labs()` labels are typeset too. Here is the first plot using only ggplot2 functions: ```{r device-math, out.width="70%"} latex_options(device_math = TRUE) ggplot(df, aes(x, y, label = eq, colour = col, size = c(14, 18, 14))) + geom_text(size.unit = "pt") + scale_colour_identity() + scale_size_identity() + labs( x = r"($\beta_1 \cdot x + \beta_0$)", y = r"($\mathrm{mpg}$)" ) + theme(axis.title = element_text(size = 14)) ``` ```{r device-math-off, include = FALSE} latex_options(device_math = FALSE) ``` Here math needs its `$` signs, so the middle label stays literal. `device_math` applies to the whole session and does not make room for tall formulas; `geom_latex()` and `element_latex()` do. See `vignette("base-graphics")`. ## Markdown labels `geom_markdown()` and `element_markdown()` take markdown with `$math$`, for labels that are more text than formula: ```{r markdown, out.width="70%"} df <- data.frame( x = 1:3, y = c(2, 3, 1), lab = c("**bold**", r"(*slope* $\beta_1$)", "`code` and $x^2$") ) ggplot(df, aes(x, y, label = lab)) + geom_point() + geom_markdown(fontsize = 14, vjust = -0.6) + ylim(0.5, 3.6) + labs( title = r"(*Fitted* model: $\hat{y} = \beta_0 + \beta_1 x$)", x = "**weight** in $10^3$ lbs", y = r"(*efficiency* $\eta$)" ) + theme( plot.title = element_markdown(fontsize = 14), axis.title.x = element_markdown(), axis.title.y = element_markdown() ) ``` `annotate("markdown", ...)` adds one label; `
` starts a new line: ```{r markdown-annotation, out.width="70%"} fit <- lm(mpg ~ wt, data = mtcars) note <- sprintf( r"(**Linear fit**
$\hat{y} = %s %s x$
$R^2 = %s$, *p* < 0.001)", round(coef(fit)[1], 1), round(coef(fit)[2], 1), round(summary(fit)$r.squared, 3) ) ggplot(mtcars, aes(wt, mpg)) + geom_point(colour = "grey65") + geom_smooth(method = "lm", se = FALSE, colour = "#1F6FB2") + annotate("markdown", x = 4.1, y = 32, label = note, size = 11, style = "strong { color: #B22222 }") + theme_minimal() ``` ### Styling `style` takes CSS, as in `vignette("markdown")`. `` styles part of a label: ```{r style, out.width="70%"} css <- " body { color: #33475B } strong { color: #B22222 } code { color: #1F6FB2 } .unit { color: grey55; font-size: smaller } " df <- data.frame( x = 1:3, y = c(2, 3, 1), lab = c("**bold** is red", "`code` is blue", 'plain with a note') ) ggplot(df, aes(x, y, label = lab)) + geom_point() + geom_markdown(style = css, fontsize = 14, vjust = -0.8) + ylim(0.5, 3.8) + labs(title = r"(**Styled** labels and $\beta_1$)", x = 'weight (1000 lbs)') + theme( plot.title = element_markdown(style = css, fontsize = 14), axis.title.x = element_markdown(style = css) ) ``` Margins, padding and backgrounds apply only to block titles (below). `latex_options(markdown_style = )` sets a default style for the session. ### Block titles A title with a heading, a list or several paragraphs is laid out as a small document, and the `body` rule styles its box: ```{r blocktitle, out.width="70%"} ggplot(mtcars, aes(wt, mpg)) + geom_point(colour = "grey40") + labs(title = r"(## Fuel economy falls with weight - slope $\beta_1 = -5.34$, *p* < 0.001 - $R^2 = 0.75$ over $n = 32$ cars)") + theme(plot.title = element_markdown(style = " body { background: #F4F7FB; padding: 10px; border: 1px solid #C7D6E5; border-radius: 4px } ")) ``` - Text does not wrap unless you give `width`; `unit(1, "npc")` suits a title. - Axis tick labels and rotated labels are never laid out as blocks.