如何在ggplot分面图的每个分面中绘制不同的grob?
解决ggplot分面中geom_grob重复显示最后一个grob的问题
问题描述
在ggplot分面图中,尝试用ggpmisc::geom_grob为每个分面添加不同的grob(如汇总统计表格),但所有分面仅显示最后一个grob。复现代码如下:
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))
问题效果图:
原因分析
当前的grobs数据框未关联分面变量Species,ggplot在分面渲染时无法将每个grob与对应分面匹配,最终所有分面都调用了列表中的最后一个grob元素。
解决方案
在grobs数据框中加入分面变量Species,让每个grob与对应的分面标签绑定,确保geom_grob能根据分面变量匹配正确的grob。
修改后的代码
library(dplyr) library(ggplot2) library(gridExtra) library(ggpmisc) 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) # 加入Species变量,关联每个grob到对应分面 grobs <- tibble( Species = c("setosa", "versicolor", "virginica"), x = 4, y = 2, grobs = list(g1,g2,g3) ) p1 + geom_grob(data=grobs, aes(x=x, y=y, label=grobs))
更简洁的批量生成方式
如果分面数量较多,可使用purrr::map批量生成grob并自动关联分面变量:
library(dplyr) library(ggplot2) library(gridExtra) library(ggpmisc) library(purrr) 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)) # 批量生成grob并绑定分面变量 grobs <- stats |> mutate( grobs = map(rowwise(), ~tableGrob(.x[, c("Mean", "SD")], rows = NULL)), x = 4, y = 2 ) p1 + geom_grob(data = grobs, aes(x = x, y = y, label = grobs))
修改后每个分面将显示对应物种的统计表格grob。
内容的提问来源于stack exchange,提问作者Claudio
相关产品推荐
相关产品推荐

