rggplot2facetgrob

Plot grobs on ggplot faceted graph


I have a faceted plot and I want to plot on each facet a different grob (say a table with summary statistics). I tried to use ggpmisc::geom_grob putting the different grobs in a list, but only the last grob is plotted in all of the facets.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(ggplot2)
library(gridExtra)
#> 
#> Attaching package: 'gridExtra'
#> The following object is masked from 'package:dplyr':
#> 
#>     combine
library(ggpmisc)
#> Loading required package: ggpp
#> 
#> Attaching package: 'ggpp'
#> The following object is masked from 'package:ggplot2':
#> 
#>     annotate

p1 <- iris |> 
  ggplot(aes(x=Petal.Length)) +
  geom_density() +
  facet_wrap(vars(Species))

stats <- iris |> 
  group_by(Species) |> 
  summarise(Mean = round(mean(Petal.Length), 3),
            SD = round(sd(Petal.Length), 3))

g1 <- filter(stats, Species == "setosa") |> tableGrob(rows=NULL)
g2 <- filter(stats, Species == "versicolor") |> tableGrob(rows=NULL)
g3 <- filter(stats, Species == "virginica") |> tableGrob(rows=NULL)

grobs <- tibble(x=4, y=2, grobs = list(g1,g2,g3))

p1 +
  geom_grob(data=grobs, aes(x=x, y=y, label=grobs))

Created on 2023-01-23 with reprex v2.0.2


Solution

  • You haven't included the faceting variable (Species) in the grobs data frame, so ggplot doesn't know how to distribute these grobs between the facets. All three tables are drawn in all three facets, and you only see the third one because it is drawn over the first two.

    If you add a Species column with the appropriate labels to your grobs data frame, then each table grob will be drawn on its corresponding facet.

    grobs <- tibble(x = 4, y = 2, grobs = list(g1, g2, g3), 
                    Species = c('setosa', 'versicolor', 'virginica'))
    
    p1 + geom_grob(data = grobs, aes(x = x, y = y, label = grobs))
    

    enter image description here