Is it possible to mark a specific plot of a facet_wrap with ggplot2?
Lets assume I have a 3x3 facet_wrap plot and I want to mark the midle one (i=2,j=2) by giving it a red border, red linecolor and red title-color. How do I do that in a nice and convenient way?
As mentioned in the comments, it's not straightforward to do what you suggest. Here's how one might go about doing it. Here I create a sample dataframe, and load both ggplot2 and grid packages.
library(ggplot2)
library(grid)
set.seed(123)
df <- data.frame(f = rep(LETTERS[1:9], 3), x = rnorm(27), y = rnorm(27))
Now, I create the basic plot. The red line is the easiest: we map the colour aesthetic to the variable we use for faceting, and set the color in scale_colour_manual:
p <- ggplot(df, aes(x, y, colour = f == "E")) +
geom_line() +
scale_colour_manual(guide = FALSE, values = c("black", "red")) +
facet_wrap("f")
For the rest, we have to edit the plot manually. We generate the plot grob and inspect it:
g <- ggplotGrob(p)
g
# TableGrob (21 x 15) "layout": 62 grobs
# z cells name grob
# 1 0 ( 1-21, 1-15) background rect[plot.background..rect.5921]
# 2 1 ( 7- 7, 4- 4) panel-1-1 gTree[panel-1.gTree.5502]
# ...
# 6 1 (12-12, 8- 8) panel-2-2 gTree[panel-5.gTree.5562]
# ...
# 51 2 (11-11, 8- 8) strip-t-2-2 gtable[strip]
# ...
# 62 10 (20-20, 4-12) caption zeroGrob[plot.caption..zeroGrob.5919]
The grobs of interest are numbers 6 and 51, corresponding to the center panel and its panel strip, respectively. Inspecting grob number 6, we see the following:
str(g$grobs[[6]])
# List of 5
# $ name : chr "panel-5.gTree.5562"
# ...
# $ children :List of 5
# ..$ grill.gTree.5560 :List of 5
# .. ..$ name : chr "grill.gTree.5560"
# ...
# .. ..$ children :List of 5
# .. .. ..$ panel.background..rect.5551 :List of 10
# ...
# .. .. .. ..$ gp :List of 4
# .. .. .. .. ..$ lwd : num 1.42
# .. .. .. .. ..$ col : logi NA
# .. .. .. .. ..$ fill: chr "grey92"
# .. .. .. .. ..$ lty : num 1
# .. .. .. .. ..- attr(*, "class")= chr "gpar"
# ...
# - attr(*, "class")= chr [1:3] "gTree" "grob" "gDesc"
Notice the col element. We assign the value red to this element:
g$grobs[[6]]$children[[1]]$children[[1]]$gp$col <- "red"
Inspecting grob 51 (which has a slightly different structure), we do the same:
g$grobs[[51]]$grobs[[1]]$children[[2]]$children[[1]]$gp$col <- "red"
This is all we need to do. Although it takes some effort to inspect the grob structures, it does not take that much code to make the modifications. To summarise, here's all we need to do:
g <- ggplotGrob(p)
g$grobs[[6]]$children[[1]]$children[[1]]$gp$col <- "red"
g$grobs[[51]]$grobs[[1]]$children[[2]]$children[[1]]$gp$col <- "red"
grid.draw(g)
to get:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With