2

Following this example I am able to add some text to each facet grid but on one panel I need 2 separate labels over each group of boxplots, similar to the spacing the labels produced by stat_compare_means. My current logic can only accommodate one label per panel. How can I prevent them from overlapping or set individual coordinates for each label?

  ID<-c('E5b','R6',"S22","E5b","R6","S22","E5b","R6","S22","E5b","R6","S22","E5b","R6","S22","E5b","R6",
      "S22","E5b","R6","S22","E5b","R6","S22","E5b","R6","S22","E5b","R6","S22")
value<-c(1.02048033657553e-05, 7.03779542465882e-07, 3.51889771232941e-07, 5.69459095210849e-06, 5.42341995438904e-07,
         1.08468399087781e-06, 1.15124329576991e-05, 2.34947611381614e-07, 4.69895222763228e-07, 1.02807349661977e-05,
         2.12704861369607e-06, 0, 1.90550741185218e-06, 1.52440592948174e-06, 0, 1.23540828390671e-06, 4.11802761302236e-07,
         0, 5.22781921260155e-06, 1.04556384252031e-06, 0, 1.71521997010029e-06, 0, 2.05826396412034e-06, 4.18012063828162e-06,
         0, 7.60021934233022e-07, 2.93951950197596e-05, 0, 2.31458228502044e-07)
condition<-c("E","E","E","E","E","E","E","E","E","E","R","R","R","R","R","R","R","R","R",
             "R","R","S","S","S","S","S","S","S","S","S")
family<-c("Unassigned","Unassigned","Siphoviridae","Unassigned","Unassigned","Siphoviridae","Unassigned","Unassigned",
          "Siphoviridae","Unassigned","Unassigned","Siphoviridae","Unassigned","Unassigned","Siphoviridae","Unassigned",
          "Unassigned","Siphoviridae","Unassigned","Unassigned","Siphoviridae","Unassigned","Unassigned","Siphoviridae",
          "Unassigned","Unassigned","Siphoviridae","Unassigned","Unassigned","Siphoviridae")
seqlength<-NA
seqlength[1]<-'1941 kb'
seqlength[2]<-'1001 kb' 
seqlength[3]<-'1214 kb'
df <- data.frame(ID,value,condition,family,seqlength)


p <- ggboxplot(df, x = "ID", y = "value",
          color = "condition", 
          palette = "jco",add = "jitter")+
          facet_wrap(~family,scales='free_x')+
          scale_y_continuous(labels = comma)+
          stat_compare_means(aes(group = condition),size=3,label="p.format") #label = "p.signif"

p + geom_text(
  data    = df,
  mapping = aes(x = -Inf, y = -Inf, label = seqlength),
  hjust   = -2,
  vjust   = -40
)
 

enter image description here

skiventist
  • 425
  • 4
  • 11

1 Answers1

3

For facetted annotations, you need to feed ggplot a data frame with the faceting variable. However, if you have the annotation attached to every single row of your data, the text will be overplotted and tend to look scrappy. A good workaround is to prepare a separate table with just the annotation info, so each label only gets plotted once:

#p <- ggboxplot(df, ]...

df_labels <- data.frame(
  family = c("Unassigned","Unassigned","Siphoviridae"),
    label = c('1941 kb', '1001 kb', '1214 kb'),
    ID = c('E5b','R6',"S22"),
    y = c(0.000028, 0.000028, 0.000028))
    #hardcoded here but could make dynamic to taste by using max(df$value) etc.


p + geom_text(
  data    = df_labels,
  mapping = aes(x = ID, y = y, 
                label = label)
)

enter image description here

Jon Spring
  • 55,165
  • 4
  • 35
  • 53
  • 1
    Nice answer (+1) Just wanted to add that we could skip the intermediate dataframe construction by doing `data = transform(df[1:3,], y = c(0.000028, 0.000028, 0.000028))` in this case. – teunbrand Feb 15 '21 at 17:34
  • Excellent suggestion, as in this case the data cycles between the three classes we need, so the first three rows provide a shortcut. – Jon Spring Feb 15 '21 at 19:13
  • It looks like the answer was accepted and then un-accepted. Did it not work as expected? – Jon Spring Feb 16 '21 at 21:56