add red shade/area to facet plot
04:53 12 Jul 2026

I have a facet grid plot where I wish to add red-shaded rectangles/areas to categories for which I don't have any observations. I remember I achieved something similar with a much simpler 3×2 facet grid with the following:

##get the table GROBS from facet_grid
g6 <- ggplot_gtable(ggplot_build(testALL))
##selectively change the color of the bottom-rigth rectangle
pp <- gtable_add_grob(g6, rectGrob(gp=gpar(col=NA, fill='indianred1', alpha=.2)), t=-8, r=-4, b=-8, l=-5)

grid.draw(pp)

However, in the former I only had to color the bottom right pane and just that was a lot of manual testing... In the current example (see code below), I have 92 panes; moreover, in each one only some parts have to be colored (see desired output Adobe modified).

So, my question is whether there is a way to do it in a more automated manner which scales to both the number of panes as well as only the areas of interest.

Code

library(lemon)
library(dplyr)
library(ggsci)
library(ggh4x)
library(ggplot2)
library(paletteer)
library(ggchicklet)
library(PalCreatoR)


color_strips <- as.data.frame(paletteer_d("ggsci::default_igv"))
strips_def <- strip_nested(

  background_x = elem_list_rect(fill=paletteer_d("wesanderson::GrandBudapest2")),
  background_y = elem_list_rect(fill=modify_pal(pal=substr(color_strips$x, 1, 7), alpha=.25, show.pal=TRUE, title="strips_col")),
  text_y = elem_list_text(face=c(rep("bold", 23), rep("plain", 23), rep("plain", 23), rep("plain", 23), rep("plain", 23)), 
                          size=c(rep(6, 23), rep(5, 92))),
  by_layer_y = FALSE
  
)

ggplot(excel_m) +
  geom_chicklet(mapping=aes(x=SAMPLE, y=COUNT, fill=V_TYPE), position="dodge2", radius=grid:: unit(1, "mm")) + 
  facet_grid2(CHR ~ GRAPH, strip=strips_def, switch="y") + theme_bw() + 
  scale_fill_npg() + guides(fill=guide_legend(title='variants', title.position='top', 
                                              title.hjust=.5, position="bottom")) +
  theme(legend.title=element_text(face='italic', size=16), legend.position='bottom', 
        panel.grid=element_blank(), axis.text.x=element_text(face='bold', 
                                                             angle=45, 
                                                             hjust=1),
      axis.title.x=element_blank(), axis.title.y=element_blank(),
      axis.text.y.right=element_text(size=5),
      axis.text.x.top=element_text(size=10),
      panel.spacing.y=unit(0.1, "lines"),
      legend.text=element_text(size=12)
      ) +
scale_y_continuous(labels=fancy_scientific,
                   position="right") + 
xlab(NULL) + 
ylab(NULL)

dput(excel_m)

excel_m <- structure(list(CHR = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 
11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 
12L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 
14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 15L, 
15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 
16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 
17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 
18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 
19L, 19L, 19L, 19L, 19L, 19L, 19L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 
20L, 20L, 20L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 
21L, 21L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 
22L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 
9L, 9L, 9L, 9L, 9L, 9L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 
23L, 23L, 23L, 23L), levels = c("chr1", "chr2", "chr3", "chr4", 
"chr5", "chr6", "chr7", "chr8", "chr9", "chr10", "chr11", "chr12", 
"chr13", "chr14", "chr15", "chr16", "chr17", "chr18", "chr19", 
"chr20", "chr21", "chr22", "chrX"), class = "factor"), GRAPH = c("clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt", "clone4_prt", "clone4_prt", "clone4_prt", "clone5_prt", 
"clone5_prt", "clone5_prt", "clone7_prt", "clone7_prt", "clone7_prt", 
"irradiated_prt", "irradiated_prt", "irradiated_prt", "clone4_prt", 
"clone4_prt", "clone4_prt", "clone5_prt", "clone5_prt", "clone5_prt", 
"clone7_prt", "clone7_prt", "clone7_prt", "irradiated_prt", "irradiated_prt", 
"irradiated_prt"), SAMPLE = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 
1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 
3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L), levels = c("clone4_12w", 
"clone5_12w", "clone7_12w", "irradiated_24h"), class = "factor"), 
    V_TYPE = structure(c(2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L), levels = c("all", 
    "SNPs", "INDELs"), class = "factor"), COUNT = c(7736, 1179, 
    8915, 7737, 1178, 8915, 7724, 1178, 8902, 7737, 1179, 8916, 
    4015, 1234, 5249, 4042, 1252, 5294, 4054, 1227, 5281, 4091, 
    1269, 5360, 56568, 14994, 71562, 56505, 14984, 71489, 56567, 
    15021, 71588, 56499, 15005, 71504, 2280, 392, 2672, 2277, 
    392, 2669, 2280, 393, 2673, 2280, 391, 2671, 1194, 315, 1509, 
    1155, 312, 1467, 1238, 330, 1568, 1244, 339, 1583, 5842, 
    1311, 7153, 7214, 1527, 8741, 7267, 1586, 8853, 7117, 1491, 
    8608, 2170, 461, 2631, 2539, 485, 3024, 2689, 532, 3221, 
    2556, 485, 3041, 490, 122, 612, 506, 124, 630, 493, 124, 
    617, 495, 125, 620, 1944, 253, 2197, 1935, 253, 2188, 1934, 
    250, 2184, 1919, 252, 2171, 1437, 223, 1660, 1436, 221, 1657, 
    1437, 220, 1657, 1446, 220, 1666, 2308, 220, 2528, 2293, 
    216, 2509, 2242, 208, 2450, 2276, 217, 2493, 43954, 11844, 
    55798, 43993, 11820, 55813, 43969, 11822, 55791, 44112, 11855, 
    55967, 2305, 414, 2719, 2303, 409, 2712, 2321, 397, 2718, 
    2272, 412, 2684, 1392, 275, 1667, 1432, 274, 1706, 1709, 
    315, 2024, 1590, 284, 1874, 4535, 1079, 5614, 5119, 1203, 
    6322, 4933, 1182, 6115, 4629, 1096, 5725, 2342, 348, 2690, 
    2351, 349, 2700, 2321, 340, 2661, 2326, 350, 2676, 62163, 
    16474, 78637, 61949, 16370, 78319, 62092, 16438, 78530, 62055, 
    16364, 78419, 66217, 17925, 84142, 66188, 17884, 84072, 66283, 
    17937, 84220, 66346, 17931, 84277, 2176, 382, 2558, 2145, 
    379, 2524, 2175, 389, 2564, 2264, 386, 2650, 5047, 912, 5959, 
    5099, 918, 6017, 5107, 911, 6018, 5141, 921, 6062, 787, 138, 
    925, 792, 140, 932, 799, 142, 941, 780, 137, 917, 23656, 
    8408, 32064, 23644, 8407, 32051, 23743, 8415, 32158, 23661, 
    8397, 32058, 1215, 118, 1333, 1167, 111, 1278, 1218, 119, 
    1337, 1242, 123, 1365)), row.names = c(NA, -276L), spec = structure(list(
    cols = list(CHR = structure(list(), class = c("collector_character", 
    "collector")), GRAPH = structure(list(), class = c("collector_character", 
    "collector")), SAMPLE = structure(list(), class = c("collector_character", 
    "collector")), V_TYPE = structure(list(), class = c("collector_character", 
    "collector")), COUNT = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), delim = "\t"), class = "col_spec"), problems = , class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"))

Desired output

output edited

ggplot2 facet-grid ggh4x