How to reference siunitx units in axis labels for ggplot2 figures?

ggplot2
knitr

#1

I asked this question on Stack Overflow 16 days ago but got no help so I am asking here!

I have a knitr Rnw file (LaTeX with embedded R) which imports the siunitx package. I declare units with \DeclareSIUnit and I would like to reference those units in axis labels in my ggplot() figures. I have tried the master branch of latex2enc but it does not do what I need. Help?

Minimum working example:

\documentclass{article}
\usepackage{siunitx}
\DeclareSIUnit{\dunit}{\SIUnitSymbolDegree Du}
\begin{document}
    <<setup, include=TRUE>>=
    library(ggplot2)
    @

    This first plot with a changed Y label should work.

    <<new-y-label, echo=TRUE>>=
    ggplot(iris, aes(Sepal.Length, Petal.Length)) + geom_line(aes(linetype=Species)) + ylab("Petal length")
    @

    I can change the label to include basic \LaTeX\ commands using the latex2exp package, which is not formally released for R version 3.4.4.

    <<latex-y-label, echo=TRUE>>=
    # devtools::install_github('stefano-meschiari/latex2exp')
    library(latex2exp)
    ggplot(iris, aes(Sepal.Length, Petal.Length)) + geom_line(aes(linetype=Species)) + ylab(TeX("$\\alpha$"))
    @

    But how do I change the Y label to reference \si{\dunit} ?

    <<does-not-work, echo=TRUE>>=
    ggplot(iris, aes(Sepal.Length, Petal.Length)) + geom_line(aes(linetype=Species)) + ylab(TeX("$\\si{\\dunit}$"))
    @

    This does not work.  Help!
\end{document}

#2

Is this issue specific to making plots inside of a LaTeX document? I'm assuming yes, since siunitx is a TeX package, not an R package (based on my rudimentary googling), but I figured I'd ask, as the pool of people who can help is probably larger if it's something that can be reproduced in R alone.

Also, could you describe your desired output more generally? It might be that there's a solution that takes a different approach.


#3

This issue is specific to making plots inside of a LaTeX document.

I have some plots which I am currently generating with ggplot() using geom_line(), xlab(), ylab(), and occasionally scale_linetype_manual() but that last part is working fine, heh. In my actual plots, the X axis represents either a magnitude of or a change in a parameter measured in degrees Brix, or °Br, while the Y axis represents time, measured in days. I'm open to alternatives to ggplot() if they solve this issue -- bonus points if they have similar functionality to facet_wrap() and facet_grid()!


#4

I meant more in terms of approach to LaTeX-ggplot integration, but I personally don't have a great suggestion either way.

This thread might be of interest:


#5

I have zero experience making ggplot2 plots inside LaTeX, so apologies if this is off the mark. My thought was that perhaps you could create the units you are after in ggplot2 directly?

library(ggplot2)

ggplot(iris, aes(Sepal.Length, Petal.Length)) + 
geom_line(aes(linetype=Species)) + 
ylab("Petal length (degrees Brix)")

ggplot(iris, aes(Sepal.Length, Petal.Length)) + 
geom_line(aes(linetype=Species)) + 
ylab(expression(paste("Petal Length (", degree, "B)")))

Would these render correctly in your Rnw file?

Cheers, Steph


#6

That does work! :sparkles: :clap:

Today I learned that knitr apparently generates its own PDFs separate from LaTeX, so my actual goal may not be achievable -- but your solution will definitely address the issue I am facing.

Thank you!


#7

try the tikzDevice package, it will call LaTeX to produce the figure and can therefore parse LaTeX macros (they need proper escaping though, which is a bit annoying).


#8

I finally had the opportunity to try tikzDevice, and it solved a problem that I didn't even notice that I had!

Not only does it use the LaTeX macros from the parent document but it also uses the document's font for all of the figures. Wow!

This is for anyone who wonders how this is done with tikzDevice:

<<tikz-device-works-too, echo=TRUE, dev='tikz'>>=
library(tikzDevice)
ggplot(iris, aes(Sepal.Length, Petal.Length)) + geom_line(aes(linetype=Species)) + ylab("$\\si{\\dunit}$")
@