Author: Paul Murrell

# The {xdvir} Package

#### Paul Murrell

The {xdvir} package provides functions for rendering LaTeX fragments in R plots.

    library(xdvir)

# 1 Rendering LaTeX in R

The plot below, produced with R, features a LaTeX-quality mathematical equation in the top-left corner. Producing an equation like this requires three things:

1. A markup language that allows us to describe the equation.

2. A typesetter that can select fonts and individual glyphs from within those fonts and determine the exact placement of each individual glyph.

3. A renderer that can draw the glyphs from the fonts that the typesetter has selected in the locations that the typesetter has determined.

The {xdvir} package allows us to use LaTeX as the markup language, a TeX engine as the typesetter, and R as the renderer. This allows us to produce high-quality LaTeX typesetting within R plots, as in the image above.

The main function in {xdvir} is `grid.latex()`, which takes a LaTeX snippet and draws it on the current R graphics device. For example, the following code describes the mathematical equation, using LaTeX code, as a character value, then draws it by calling `grid.latex()` with the character value as the first argument.

Because LaTeX code tends to contain a large number of backslashes, the code below uses the `r"(...)"` syntax for raw character constants, so that we do not have to escape each backslash with a double backslash.

    tex <- r"(\huge $\Phi(z) = \frac{1}{\sqrt{2\pi}} \cdot e^{-\frac{z^2}{2}}$)"

    grid.latex(tex)

# 2 LaTeX annotations in plots

The function `grid.latex()` only provides a low-level interface for drawing LaTeX snippets as part of {grid} output. However, there are ways to combine {grid} output with higher-level plotting packages.

For example, we can use {grid} within panel functions in the {lattice} package (Sarkar 2008). The following code draws a {lattice} plot and adds the mathematical equation in the top-left corner. This demonstrates that the `grid.latex()` function has arguments `x`, `y`, `hjust`, and `vjust` for positioning the LaTeX output.

    library(lattice)

    x <- seq(-4, 4, length.out=100)
    df <- data.frame(x=x, y=dnorm(x))

    xyplot(y ~ x, df, type="l",
           panel=function(...) {
               panel.xyplot(...)
               grid.latex(tex,
                          x=unit(2, "mm"),
                          y=unit(1, "npc") - unit(2, "mm"),
                          hjust="left", vjust="top")
           })

If we want to add {grid} output to a {graphics} plot, we can use the {gridGraphics} package (Murrell 2015; Murrell and Wen 2020). For example, the following code draws a {graphics} plot, uses `gridGraphics::grid.echo()` to convert it to {grid}, navigates to the {grid} viewport that represents the main plot region, and draws the mathematical equation in the top-left corner.

    library(gridGraphics)

    plot(y ~ x, df, type="l")
    grid.echo()
    downViewport("graphics-plot-1")
    grid.latex(tex,
               x=unit(2, "mm"),
               y=unit(1, "npc") - unit(2, "mm"),
               hjust="left", vjust="top")

We can add {grid} output to {ggplot2} plots (Wickham 2016) with the {gggrid} package (Murrell 2021, 2022). The following code uses the `latexGrob()` function to generate a “graphical object” for {ggplot2} to draw, rather than drawing the output immediately as `grid.latex()` does, and passes that to `gggrid::grid_panel()` so that the mathematical equation is added in the top-left corner of the plot.

    library(gggrid)

    gg <- ggplot(df) +
        geom_line(aes(x, y))

    gg +
        grid_panel(latexGrob(tex,
                             x=unit(2, "mm"),
                             y=unit(1, "npc") - unit(2, "mm"),
                             hjust="left", vjust="top"))

Another way to do this in {ggplot2} is with `ggplot2::annotation_custom()`, though precisely positioning the annotation may be less convenient.

# 3 LaTeX labels in {ggplot2}

The {xdvir} package also provides integration with labels in {ggplot2} plots. This allows, for example, the title of a plot to contain LaTeX code, as shown in the image below. For this to work, the relevant theme element must be set using `element_latex()`, as shown in the code below.

    gg +
        labs(title=paste("The Normal Distribution:", tex)) +
        theme(plot.title=element_latex())

Although the need is probably less, for completeness, there is also a `geom_latex()` for adding LaTeX-styled data symbols. For example, the following code adds LaTeX text labels to a dot plot.

    samples <- data.frame(x=rnorm(50), sample=rep(1:5, each=10))
    means <- aggregate(samples$x, list(sample=samples$sample), mean)
    means$label <- paste0("$\\bar x_", means$sample, "$")

    ggplot(samples) +
        geom_vline(xintercept=0, linetype="solid", colour=1, linewidth=.5) +
        geom_point(aes(x, sample), size=4, alpha=.5) +
        geom_point(aes(x, sample), data=means, colour=2, size=4) +
        geom_latex(aes(x, sample, label=label), data=means,
                   size=6, vjust=-.4, colour=2) +
        scale_y_continuous(expand=expansion(.25))

# 4 Related packages

The {xdvir} package provides similar functionality to the {gridtext} and {ggtext} packages (Wilke and Wiernik 2022b, 2022a) and the {marquee} package (Pedersen and Mitáš 2024). The main difference is the markup language that is supported. Where those packages are built on markdown, {xdvir} is built on LaTeX, with all of the joy and pain that that brings.

# 5 Limitations

The {xdvir} package relies on the glyph rendering support that was added to the R graphics engine in R version 4.3.0 (Murrell, Pedersen, and Urbanek 2023). Furthermore, this support is only available on specific graphics devices: the core `pdf()`, Cairo-based devices, and `quartz()` devices, plus the devices provided by the {ragg} package (Pedersen and Shemanarev 2024). R Studio users should set the graphics backend to “AGG” or “cairo” (if either of those is not the default).

The {xdvir} package also relies on there being a TeX installation. When the package is attached, it reports on the TeX features that it can find (see the top of this document for an example). If TeX is not found, the simplest solution is to use `tinytex::install_tinytex()`.

# References

Murrell, Paul. 2015. “The gridGraphics Package.” The R Journal 7 (1): 151–62. https://doi.org/10.32614/RJ-2015-012.

———. 2021. “Accessing ’grid’ from ’ggplot2’.” 2021-01. Department of Statistics, The University of Auckland. https://doi.org/10.17608/k6.auckland.14703846.

———. 2022. gggrid: Draw with ’grid’ in ’ggplot2’. https://CRAN.R-project.org/package=gggrid.

Murrell, Paul, Thomas Lin Pedersen, and Simon Urbanek. 2023. “Rendering Typeset Glyphs in R Graphics.” 2023-01. Department of Statistics, The University of Auckland. https://doi.org/10.17608/k6.auckland.22774079.

Murrell, Paul, and Zhijian Wen. 2020. GridGraphics: Redraw Base Graphics Using ’Grid’ Graphics. https://CRAN.R-project.org/package=gridGraphics.

Pedersen, Thomas Lin, and Martin Mitáš. 2024. marquee: Markdown Parser and Renderer for R Graphics. https://CRAN.R-project.org/package=marquee.

Pedersen, Thomas Lin, and Maxim Shemanarev. 2024. ragg: Graphic Devices Based on Agg. https://CRAN.R-project.org/package=ragg.

Sarkar, Deepayan. 2008. Lattice: Multivariate Data Visualization with R. New York: Springer. http://lmdvr.r-forge.r-project.org.

Wickham, Hadley. 2016. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York. https://ggplot2.tidyverse.org.

Wilke, Claus O., and Brenton M. Wiernik. 2022a. ggtext: Improved Text Rendering Support for ’ggplot2’. https://CRAN.R-project.org/package=ggtext.

———. 2022b. gridtext: Improved Text Rendering Support for ’Grid’ Graphics. https://CRAN.R-project.org/package=gridtext.