如何在ggplot2中将stat_summary绘制于图表外部上方?
解决方案:将ggplot2统计信息移至图表外部
要把stat_summary的统计文本移到图表外部,最简便的方式是提前计算分组统计数据,再通过geom_text将文本定位到扩展后的坐标轴区域,同时调整边距避免文本截断。以下是修改后的完整代码:
步骤1:定义统计函数并预处理统计数据
library(dplyr) library(ggplot2) # 定义统计文本生成函数(修正原代码中std()为R内置的sd()) stats_PFAS10 <- function(y) { paste( "Anzahl =", length(y), "\n", "Mittelwert =", round(mean(y), 2), "\n", "KI1 = ", round(mean(y) - qnorm(0.95)*sd(y)/sqrt(length(y)), 2), "\n", "KI2 = ", round(mean(y) + qnorm(0.95)*sd(y)/sqrt(length(y)), 2), "\n", "1.Q = ", quantile(y, probs=0.25, na.rm=TRUE), "\n", "Median =", round(median(y), 2), "\n", "3.Q = ", quantile(y, probs=0.75, na.rm=TRUE), "\n", "90 % Q = ", quantile(y, probs=0.9, na.rm=TRUE), "\n", "STD = ", round(sd(y),2), "\n", "Varianz =", round(var(y),2), "\n", "Max =", round(max(y),2), "\n", "Min =", round(min(y),2) ) } # 按Quelle和Probenart分组计算统计文本 stats_data <- PFAS_data %>% mutate(Quelle = factor(Quelle, levels=c('Siedlung', 'Hauptpunktquelle')), Probenart = factor(Probenart, levels=c('OBER-0-20', 'UNTER20-40'))) %>% group_by(Quelle, Probenart) %>% summarise(label = stats_PFAS10(pfas10), .groups = "drop") # 计算x轴(翻转后为y轴)的扩展范围,预留文本空间 max_pfas <- max(PFAS_data$pfas10, na.rm = TRUE) x_extend <- max_pfas * 1.3 # 扩展30%空间,可根据文本长度调整
步骤2:绘制图表并添加外部统计文本
PFAS_data %>% mutate(Quelle = factor(Quelle, levels=c('Siedlung', 'Hauptpunktquelle')), Probenart = factor(Probenart, levels=c('OBER-0-20', 'UNTER20-40'))) %>% ggplot(mapping = aes(x = pfas10, y = Probenart))+ geom_boxplot(aes(fill = Probenart), col = "black", outlier.size = 2, outlier.shape = 1, width=0.5, na.rm = TRUE)+ geom_jitter(width = 0.1, color = "grey46", na.rm = TRUE )+ facet_grid(~ Quelle, scale = "free", space = "free") + stat_boxplot(geom = 'errorbar', width = 0.2, na.rm = TRUE) + # 将统计文本放置到扩展后的右侧区域 geom_text(data = stats_data, aes(x = x_extend, y = Probenart, label = label), hjust = 0, vjust = 0.5, size = 3) + # 设定x轴范围,预留文本空间 coord_flip(xlim = c(0, x_extend)) + theme_bw() + theme(legend.position="bottom", axis.title.x = element_text(size=11), axis.text.x = element_blank(), axis.title.y = element_text(size=14), axis.text.y = element_text(size=12), strip.text.x = element_text(size = 12, face = "bold"), legend.background = element_rect(size=0.5, linetype="solid", colour ="black"), text=element_text(family="sans"), # 增加右侧边距,避免文本被截断 plot.margin = margin(5, 60, 5, 5))
关键调整说明
- 提前计算统计数据:避免
stat_summary在图表内部占用空间,同时更精准控制文本位置。 - 扩展坐标轴范围:通过
x_extend设置超出数据最大值的范围,为文本预留空间。 - 调整边距:
plot.margin增加右侧边距,确保统计文本完整显示。 - 文本对齐:
hjust=0让文本左对齐,紧贴图表数据区域,视觉上更协调。
内容的提问来源于stack exchange,提问作者Celina Steffani
相关产品推荐
相关产品推荐

