I am using facet_grid
to draw several plots and I am wondering how to add some extra information as a caption in each individual plot.
I managed to add information in the title of each plot (in order to add the Kruskal-Wallis p-value), but I would like to add more info below each plot (as a caption).
Here is a reproducible example:
library(ggplot2)
library(dplyr)
set.seed(1234)
Gene <- floor(runif(25, min=0, max=101))
Age <- floor(runif(25, min=18, max=75))
Group <- c("Group1", "Group1", "Group3", "Group2", "Group1", "Group3", "Group2", "Group2", "Group2", "Group1", "Group1", "Group3", "Group1", "Group2", "Group1", "Group2", "Group3", "Group1", "Group3", "Group3", "Group2", "Group1", "Group3", "Group3","Group2")
df <- data.frame(Gene, Age, Group)
df$Group <- as.factor(df$Group)
mybreaks <- seq(min(df$Age)-1, to=max(df$Age)+10, by=10)
df$groups_age <- cut(df$Age, breaks = mybreaks, by=10)
bp <- ggplot(df, aes(x=groups_age, y=Gene, group=groups_age)) +
geom_boxplot(aes(fill=groups_age)) +
facet_grid(. ~ Group)
bp
pval <- df %>%
group_by(Group) %>%
summarize(Kruskal_pvalue = kruskal.test(Gene ~ groups_age)$p.value)
# This is to create new labels for the facetgrid where we can show the phenotype and the KW pvalue.
labels <- c(paste('Group 1\n KW p-val:', signif(subset(pval$Kruskal_pvalue, pval$Group=="Group1"), digits = 3)),
paste('Group 2\n KW p-val:', signif(subset(pval$Kruskal_pvalue, pval$Group=="Group2"), digits = 3)),
paste('Group 3\n KW p-val:', signif(subset(pval$Kruskal_pvalue, pval$Group=="Group3"), digits = 3)))
df$KW <- factor(df$Group, levels = levels(df$Group), labels = labels)
bp <- ggplot(df, aes(x=groups_age, y=Gene, group=groups_age)) +
geom_boxplot(aes(fill=groups_age)) +
facet_grid(. ~ KW) +
theme(legend.position="none")
bp
This is the result of the code above:
This is the only way that I could think of if I want to add info about each plot as a caption.
df_group1 <- df[df$Group == "Group1",]
df_group2 <- df[df$Group == "Group2",]
df_group3 <- df[df$Group == "Group3",]
myfunction <- function(DF){
df <- as.data.frame(table(DF$groups_age))
# This is to add ": n = " to the first column
df$Var1 <- paste(df$Var1, ": n = ", sep = "")
# We join both columns in one to have the result together.
df$X <- paste(df$Var1, df$Freq)
# We save that column into a variable
vec <- df[["X"]]
return(vec)
}
numb_group1 <- myfunction(df_group1)
numb_group1 <- paste(numb_group1, collapse = "; ")
numb_group2 <- myfunction(df_group2)
numb_group2 <- paste(numb_group2, collapse = "; ")
numb_group3 <- myfunction(df_group3)
numb_group3 <- paste(numb_group3, collapse = "; ")
numb_all <- c(numb_group1, numb_group2, numb_group3)
bp <- bp + labs(caption = paste0("Group 1: n = ", nrow(subset(df, df$Group=="Group1")),
"\n",
" Groups: ", numb_all[1],
"\n",
"\n",
"Group 2: n = ", nrow(subset(df, df$Group=="Group2")),
"\n",
" Groups: ", numb_all[2],
"\n",
"\n",
"Group 3: n = ", nrow(subset(df, df$Group=="Group3")),
"\n",
" Groups:", numb_all[3]
)) + theme(legend.position="none",
plot.caption = element_text(hjust = 0, face= "italic")) #Default is hjust=1
bp
However, I would like to improve my code and find another way (if it exists) to put each info below to each individual plot.
Does anyone have an idea of what it can be done?
Thanks very much in advance