Search code examples
rggplot2ggtitle

Is there a way to have the information from stat_poly_eq() be printed in the subtitle of a ggplot?


Is there a method to move the output information from stat_poly_eq() to a subtitle? Or is it not possible? I have about 60 plots to create and it would be awesome to have this!

I tried moving it within ggtitle() but didn't have any luck. I tried moving the stat_poly_eq by editing theme() but didn't have any luck either

Packages:

library(ggplot2)
library(ggpmisc)

Data:

t1c11<-structure(list(Year = c(2000, 2001, 2002, 2003, 2004, 2000, 2001, 
2002, 2003), TreeCover = c(48.852632, 50.463158, 51.294737, 52.663158, 
52.747368, 57, 54.6, 42.066667, 51), TC_Avg3 = c(NA, 50.203509, 
51.4736843333333, 52.2350876666667, 52.045614, NA, 51.2222223333333, 
49.2222223333333, 47.8), Type = structure(c(30L, 30L, 30L, 30L, 
30L, 1L, 1L, 1L, 1L), levels = c("C 1-1", "C 1-2", "C 1-3", "C 1-4", 
"C 1-5", "C 1-6", "C 2-1", "C 2-2", "C 2-3", "C 2-4", "C 3-1", 
"C 3-2", "C 3-3", "C 3-4", "C 4-1", "C 4-2", "C 4-3", "C 4-4", 
"C 5-1", "C 5-2", "C 5-3", "C 6-1", "C 6-2", "C 6-3", "C 6-4", 
"C 7-1", "C 7-2", "C 7-3", "C 7-4", "T 1", "T 2"), class = "factor")), row.names = c(1L, 
2L, 3L, 4L, 5L, 47L, 48L, 49L, 50L), class = "data.frame")

Plot:

ggplot(t1c11, aes(x=Year, y=TC_Avg3, colour = Type)) +
  geom_point() +
  geom_smooth(span=2) +
  scale_colour_manual(values=c('#7a7a7a','#2c9399'))+
  stat_poly_eq(use_label(c("eq", "R2", "p")))+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))+
  ggtitle(label = "Test")

Thank you in advance!


Solution

  • To move the output of stat_poly_eq() to the subtitle, you need to assign the ggplot() to an object, extract the equation labels from it, and then insert the labels back to the object as a subtitle. The tricky part of this process is how to meet three combined requirements: (1) to display multiple equations as a single subtitle (2) to maintain nice display of the mathematical formula (3) to maintain their respective text colors.

    I have not yet found a solution that satisfies all of the requirements easily, so here I offer two not-optimal solutions:

    Solution #1: Rewriting Equations in HTML to Get Colored Subtitle

    library(ggplot2)
    library(ggpmisc)
    library(ggtext)
    basic_plot <- ggplot(t1c11, aes(x = Year, y = TC_Avg3, colour = Type)) +
      geom_point() +
      geom_smooth(span = 2) +
      scale_colour_manual(values = c("#7a7a7a", "#2c9399")) +
      theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) +
      ggtitle(label = "Test")
    eq_plot <- basic_plot + stat_poly_eq(use_label(c("eq", "R2", "p")))
    eq_plot
    plot_object <- ggplot_build(eq_plot)
    labels_df <- plot_object$data[[3]]["label"]
    combined_labels <- "<span style='color:#7a7a7a;'><i>y</i> = 3.48 &times; 
    10<sup>+3</sup> &minus; 1.71 x, <i>R</i><sup>2</sup> = 0.99, <i>P</i> = 0.062</span><br>
                            <span style='color:#2c9399;'><i>y</i> = &minus; 1.21 &times; 
    10<sup>+3</sup> + 0.629 x, <i>R</i><sup>2</sup> = 0.78, <i>P</i> = 0.114</span>"
    
    basic_plot + labs(subtitle = combined_labels) +
      theme(plot.subtitle = element_textbox_simple())
    

    The result:

    enter image description here

    Solution #2: No Equation Rewrite, but Subtitle Not Colored

    library(ggplot2)
    library(ggpmisc)
    basic_plot <- ggplot(t1c11, aes(x = Year, y = TC_Avg3, colour = Type)) +
      geom_point() +
      geom_smooth(span = 2) +
      scale_colour_manual(values = c("#7a7a7a", "#2c9399")) +
      theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) +
      ggtitle(label = "Test")
    eq_plot <- basic_plot + stat_poly_eq(use_label(c("eq", "R2", "p")))
    eq_plot
    plot_object <- ggplot_build(eq_plot)
    labels_df <- plot_object$data[[3]]["label"]
    combined_labels <- paste0("atop(C~1-1: ", labels_df[1, ], ", T~1: ", labels_df[2, ], ")")
    basic_plot + labs(subtitle = str2expression(combined_labels))
    

    The result:

    enter image description here