ggplot annotate each facet with different geom_rect dimensions

I am trying to annotate each facet of my ggplot with a different geom_rect object.
Reproducible example:

a <- c(x= rnorm(30, mean = 100, sd=2))
b <- c(rep(c("X", "Y"), 30))
c <- c(rep("F", 15), rep("M",15))
abc <- data.frame(a, b, c)

This is my ggplot:

ggplot(abc, aes(x = b , y = a, fill=b)) +
geom_boxplot(alpha= 0.8) +
geom_point(position = position_dodge(width=0.75))+
ylab(label = "a")+
scale_fill_manual(values = c("blue", "red"))+
stat_compare_means(label.x.npc = "center")+ 
facet_wrap(~c)

I’ve used the following code for ggplots before.

annotate("rect",
           xmin = -Inf, xmax = Inf,
           ymin = 90, ymax = 100,
           fill= "grey", alpha= 0.4)

But now I want to annotate each facet F and M separately.
For F, I want to annotate y spanning from 90 to 100,
For M, I want to annotate y spanning from 100 to 110,
x will -inf to inf for both

I read about using geom_rect and some dummy df for this but cannot understand how to use it for such a case. Any help is greatly appreciated!

>Solution :

Just create a data frame called annotations and use it as the data argument of a standard geom_rect:

library(ggplot2)

a <- c(x = rnorm(30, mean = 100, sd = 2))
b <- c(rep(c("X", "Y"), 30))
c <- c(rep("F", 15), rep("M", 15))
abc <- data.frame(a, b, c)
#> Warning in data.frame(a, b, c): row names were found from a short variable and
#> have been discarded

annotations <- data.frame(
  ymin = c(90, 105),
  ymax = c(110, 108),
  c = c("F", "M")
)
annotations
#>   ymin ymax c
#> 1   90  110 F
#> 2  105  108 M

ggplot(abc, aes(x = b, y = a, fill = b)) +
  geom_rect(
    data = annotations,
    mapping = aes(ymin = ymin, ymax = ymax, xmin = -Inf, xmax = Inf,
      x = NULL, y = NULL), fill = "grey") +
  geom_boxplot() +
  ylab(label = "a") +
  scale_fill_manual(values = c("blue", "red")) +
  facet_wrap(~c)

Created on 2022-06-24 by the reprex package (v2.0.0)

Leave a Reply