ggplot2 facet_wrap分面图:不同面板添加对应文本的问题
问题:为ggplot2分面图的不同面板添加专属文本
我有一个包含16937行、4个变量的评分数据集,变量分别为Subject、Distance_from_trap_F、type、rate,前50行数据结构如下:
structure(list(Subject = c(110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L, 110L), type = structure(c(1L, 2L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 2L, 2L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L), levels = c("Affective Valence", "Semantic Valence"), class = "factor"), rate = c(25L, 14L, 8L, 0L, 17L, 0L, 16L, 0L, 16L, 3L, 22L, 24L, 24L, 14L, 1L, 0L, 6L, 22L, 21L, 18L, 13L, 19L, 21L, 5L, 12L, 1L, 22L, 20L, 24L, 0L, 6L, 3L, 11L, 15L, 15L, 13L, 20L, 15L, 31L, 0L, 20L, 7L, 33L, 15L, 28L, 28L, 12L, 7L, 0L, 13L), Distance_from_trap_F = structure(c(3L, 4L, 1L, 1L, 3L, 1L, 2L, 1L, 2L, 1L, 4L, 4L, 2L, 2L, 1L, 1L, 2L, 2L, 4L, 3L, 4L, 3L, 4L, 2L, 1L, 1L, 4L, 4L, 4L, 1L, 2L, 1L, 2L, 2L, 3L, 3L, 4L, 3L, 4L, 1L, 3L, 2L, 4L, 3L, 4L, 4L, 2L, 2L, 1L, 3L), levels = c("0", "1", "2", "3"), class = "factor")), row.names = c(NA, 50L), class = "data.frame")
我使用ggplot2的facet_wrap函数按type变量(包含Affective Valence、Semantic Valence两个水平)绘制分面图,希望为两个面板分别添加不同文本:“good”显示在左侧Affective Valence面板,“n.s”显示在右侧Semantic Valence面板。
我尝试构建了如下文本数据框:
Graph_data_text <- data.frame(label = c("good","n.s"), group = names(table(Mid_Maze$type)))
并在绘图代码中调用geom_text:
geom_text(data=Graph_data_text,x=3.5, y=22, aes(label = label),family="sans",size=3,inherit.aes=FALSE)
但目前“good”和“n.s”同时出现在两个面板中,完整绘图代码如下:
H2_Mid_graph <- Mid_Maze%>%group_by(Subject,Distance_from_trap_F,type )%>%dplyr::summarise(rate=mean(rate))%>% ggplot(aes(x=Distance_from_trap_F,y=rate,fill=Distance_from_trap_F))+facet_wrap(~type)+ geom_violin(trim=TRUE,position=position_dodge(width=0.75),width=1.0,show.legend = FALSE)+geom_text(data=Graph_data_text,x=3.5, y=22, aes(label = label),family="sans",size=3,inherit.aes=FALSE)
解决方案
问题出在文本数据框的分组变量与分面变量不匹配,且geom_text没有关联分面变量,导致所有文本被渲染到每个面板中。以下是修正步骤:
1. 修正文本数据框
将文本数据框的分组列改为与分面变量type完全一致的名称和水平值,避免顺序或名称不匹配的问题:
Graph_data_text <- data.frame( label = c("good", "n.s"), type = c("Affective Valence", "Semantic Valence") # 与原数据的type因子水平完全对应 )
2. 修改geom_text的映射
在geom_text的美学映射中加入type变量,让ggplot自动将文本分配到对应的分面面板:
geom_text(data=Graph_data_text, aes(x=3.5, y=22, label=label, type=type), family="sans", size=3)
完整修正后的绘图代码
H2_Mid_graph <- Mid_Maze %>% group_by(Subject, Distance_from_trap_F, type) %>% dplyr::summarise(rate=mean(rate), .groups="drop") %>% # 添加.groups避免分组残留警告 ggplot(aes(x=Distance_from_trap_F, y=rate, fill=Distance_from_trap_F)) + facet_wrap(~type) + geom_violin(trim=TRUE, position=position_dodge(width=0.75), width=1.0, show.legend=FALSE) + geom_text(data=Graph_data_text, aes(x=3.5, y=22, label=label, type=type), family="sans", size=3)
关键说明
- 文本数据框必须包含与分面变量同名同值的列,这样ggplot才能识别每个文本属于哪个分面。
- 若保留
inherit.aes=FALSE,需要在aes中明确写出所有需要映射的变量(包括type),否则无法关联分面。 - 添加
.groups="drop"是为了消除dplyr分组后可能出现的警告,不影响绘图结果。
内容的提问来源于stack exchange,提问作者Orit Heimer
相关产品推荐
相关产品推荐

