Search code examples
rggplot2latexggtext

How to use LaTeX expression in textbox of ggplot


I have below ggplot :

library(ggplot2)
library(ggtext)
library(ggdist)
library(latex2exp)

set.seed(123)
DF <- rbind(data.frame('Label' = 'A', val = rnorm(200, 5)), 
            data.frame('Label' = 'B', val = rnorm(500, 10)))

ggplot(DF, aes(Label, val)) +
  stat_dots(aes(fill = Label)) +
  geom_textbox(aes(-Inf, -Inf, hjust = 0, vjust = 0, label = parse(text = TeX(r'(\tau)'))), data.frame())

Basically I want to write LaTeX syntax inside a textbox in ggplot window. Here I have given a small example, however in my original case I have a big LaTeX expression.

With above code, I am getting below error :

Don't know how to automatically pick scale for object of type expression. Defaulting to continuous.
Error: Aesthetics must be valid data columns. Problematic aesthetic(s): label = parse(text = TeX("\\tau")). 
Did you mistype the name of a data column or forget to add after_stat()?

Any pointer how to use LaTeX within a textbox in ggplot will be very helpful.

Thanks for your pointer.


Solution

  • ?latex2exp::latex2exp_supported() doesn't seem to include tau and can thus not translate it to plotmath. A workaround is to draw an empty textbox and use annotate() to put a layer on top of it, which can take LaTex, as suggested by Svannoy here.

    ggplot(DF, aes(Label, val)) +
      stat_dots(aes(fill = Label)) +
      geom_textbox(x= -Inf, y= -Inf, hjust = 0, vjust = 0, label = "") +
      annotate(geom='text',
               x= -Inf, y= -Inf, hjust = 0, vjust = 0,
               label= TeX("    $\\hat{Y} = B_0 + B_1X_1",
                         output='character'), parse = TRUE)
    

    That gives the following plot.

    enter image description here

    However, there are still some unanswered questions - what to do with unsupported expressions, such as tau?

    The output of that TeX call is

    "paste(' ','',hat(paste('Y')),'',phantom() == phantom(),'B',phantom() [ {paste('0')} ],'',phantom() + phantom(),'B',phantom() [ {paste('1')} ],'X',phantom() [ {paste('1')} ],'')" 
    

    Rather than messing with that, and other than a full implementation such as the latex2expr package backend, we can manually insert it using another annotate. Given, this isn't pretty code.

    ggplot(DF, aes(Label, val)) +
      stat_dots(aes(fill = Label)) +
      geom_textbox(x= -Inf, y= -Inf, hjust = 0, vjust = 0, label = "") +
      annotate(geom='text',
               x= -Inf, y= -Inf, hjust = 0, vjust = 0,
               label= TeX("    $\\hat{Y} = B_0 + B_1X_1",
                                 output='character'), parse = TRUE) +
      annotate(geom = 'text',
               x= -Inf, y= -Inf, hjust = -23.5, vjust = -0.20,
               label = sprintf('%s', "\u03C4"), parse = T)
    

    Where tau is a unicode representation. Lastly, the clunky part, is adjusting variables to get it at the right spot.

    annotated with tau