2
votes

I have attached multiple plots to one page using grid.arrange.

Is there a way to label each plot with "(a)","(b)" etc...

I have tried using geom_text but it does not seem compatible with my plots....

my plots

.... as you can see, geom_text has some strange interaction with my legend symbols.

I will show an example using the mtcars data of what I am trying to achieve. THe alternative to geom_text I have found is "annotate" which does not interact with my legend symbols. However, it is not easy to label only one facet....

q1=ggplot(mtcars, aes(x=mpg, y=wt)) + 
geom_line() +
geom_point()+
facet_grid(~cyl)+
annotate(geom="text", x=15, y=12, label="(a)",size=8,family="serif")

q2=ggplot(mtcars, aes(x=mpg, y=wt,)) + 
geom_line() +
geom_point()+
facet_grid(~cyl)+
annotate(geom="text", x=15, y=12, label="(b)",size=8,family="serif")


geom_text(x=15, y=5,size=8, label="(b)")

gt1 <- ggplotGrob(q1)
gt2 <- ggplotGrob(q2)


grid.arrange(gt1,gt2, ncol=1)

mtcars example

Therefore, my question is, is there a way to label plots arranged using grid.arrange, so that the first facet in each plot is labelled with either a, or b or c etc...?

2
Yepp, you can use cowplot. I've documented a list of packages that handle arranging plots in my post here. - Roman Luštrik

2 Answers

2
votes

You can use ggarrange from ggpubr package and set labels for each plot using the argument labels:

library(ggplot2)
library(ggpubr)
q1=ggplot(mtcars, aes(x=mpg, y=wt)) + 
  geom_line() +
  geom_point()+
  facet_grid(~cyl)+
  annotate(geom="text", x=15, y=12, label="(a)",size=8,family="serif")

q2=ggplot(mtcars, aes(x=mpg, y=wt,)) + 
  geom_line() +
  geom_point()+
  facet_grid(~cyl)+
  annotate(geom="text", x=15, y=12, label="(b)",size=8,family="serif")                                                         

ggarrange(q1,q2, ncol = 1, labels = c("a)","b)"))

enter image description here

Is it what you are looking for ?

1
votes

If you set inherit.aes=FALSE, you can prevent it from interring:

ggplot(mtcars, aes(x=mpg, y=wt,col=factor(cyl))) + 
geom_line() +
geom_point()+
geom_text(inherit.aes=FALSE,aes(x=15,y=12,label="(a)"),
size=8,family="serif")+
facet_grid(~cyl)

enter image description here

If you want to only label the first facet (hope I got you correct), I think the easiest way to specify a data frame, e.g if we want only something in the first,

#place it in the first
lvl_data = data.frame(
x=15,y=12,label="(a)",
cyl=levels(factor(mtcars$cyl))[1]
)

ggplot(mtcars, aes(x=mpg, y=wt,col=factor(cyl))) + 
    geom_line() +
    geom_point()+
    geom_text(data=lvl_data,inherit.aes=FALSE,
aes(x=x,y=y,label=label),size=8,family="serif")+
    facet_grid(~cyl)

enter image description here