Search code examples
rggplot2formattinglabelfacet-wrap

How do I add formatted text with a variable to a ggplot that is facet wrapped?


I'm trying to figure out how to add a nice R^2 = value to each subplot.

Right now I am able to add the value (from a separate dataframe) I want on the plot, but I don't know how to add an "R^2 =" preceding it that is italicized and superscripted.

Any advice appreciated. Thank you for your time!

example_df <- data.frame(x = c(1,2,5,7,8,9,10),
                         y = c(1,3,5,7,8, 9, 10),
                         grp = c("a", "a", "b","b","b", "c", "c"))

grp_info <- data.frame( grp = c("a", "b", "c"),
                        num = c(0.5, 0.75, 1))
  
plt <- ggplot(example_df, aes(x = x, y=y, group = grp)) +
  geom_point() + 
  facet_wrap(vars(grp), ncol = 2, scales = "free")+
  annotate(geom = "text", x = -Inf, y = Inf, label = grp_info$num, hjust = 0, vjust =1)

print(plt)

If I wanted just the "R^2 = " formatted nicely, then the following works, but it doesn't allow me to add a value from a separate dataframe.

plt <- ggplot(example_df, aes(x = x, y=y, group = grp)) +
  geom_point() + 
  facet_wrap(vars(grp), ncol = 2, scales = "free")+
  annotate(geom = "text", x = -Inf, y = Inf, label = paste("paste(italic(R) ^ 2,\"=\")"), parse = TRUE, hjust = 0, vjust =1)

The final point I belatedly raised in the comments was that ideally this addition would be multiline, allowing addition of another variable expression.


Solution

  • You can use plotmath::atop, described here, to get a line break in the expression that parses. It's a pretty messy construction, but it works. Here's an example:

    library(tidyverse)
    
    example_df <- data.frame(
      x = c(1, 2, 5, 7, 8, 9, 10),
      y = c(1, 3, 5, 7, 8, 9, 10),
      grp = c("a", "a", "b", "b", "b", "c", "c")
    )
    
    grp_info <- data.frame(grp = c("a", "b", "c"),
                           num = c(0.5, 0.75, 1),
                           rmse = c(4, 5, 6))
    
    ggplot(example_df, aes(x = x, y = y, group = grp)) +
      geom_point() +
      facet_wrap(vars(grp), ncol = 2, scales = "free") +
      geom_text(
        data = grp_info,
        aes(
          x = -Inf,
          y = Inf,
          label = paste0("atop(", "italic(R)^2", "==", num,",", "RMSE", "==", rmse, ")")
        ),
        parse = TRUE,
        hjust = 0,
        vjust = 1
      )
    

    Created on 2021-03-25 by the reprex package (v1.0.0)