如何在ggplot2中按因子及水平便捷绘制均值与标准差图表?
问题
有没有简便方法在geom_point()图表中添加均值(mean)和标准差(sd)?需要按Measurement_type、Rep、Pollution、Temp这些因子的水平分组展示,而且不想手动计算均值、标准差再合并数据框,有没有内置功能可以直接用?
我的数据结构如下:
str(df) 'data.frame': 138 obs. of 7 variables: $ Measurement_type: Factor w/ 3 levels "block_w_same_oil",..: 2 2 2 2 2 2 2 2 2 2 ... $ BDV : num 45.2 64 77 70.2 67.9 55.7 59.8 67.4 75.1 75.2 ... $ Temp : Factor w/ 2 levels "cold","warm": 1 1 1 1 1 1 1 1 1 1 ... $ Temp_C : num 20.1 20.1 20.1 20.1 20.1 20.1 20.1 20.5 20.5 20.5 ... $ Pollution : Factor w/ 2 levels "clean","polluted": 1 1 1 1 1 1 1 1 1 1 ... $ Step : num 1 2 3 4 5 6 1 2 3 4 ... $ Rep : Factor w/ 5 levels "M1","M2","M3",..: 1 1 1 1 1 1 2 2 2 2 ...
目前用的代码如下,生成的图可视化效果不好,还没加上类似geom_ribbon的标准差区域:
df %>% ggplot(aes(x = Step, y = BDV, colour = Measurement_type, shape = Rep), alpha = 0.8) + geom_point(aes(colour = Measurement_type), size = 3) + stat_summary(fun.data = 'mean_sdl', geom = 'smooth') + xlab("Step") + ylab("BDV / kV") + theme_tq()
解决方案
不用手动计算统计量,ggplot2的stat_summary()可以直接实现需求,针对你的场景可以这样优化:
- 添加均值线+标准差区域:用两次
stat_summary,一次生成均值线,一次生成标准差填充区域(类似geom_ribbon)。fun.data = mean_sdl默认计算均值±2倍标准差,如果你要1倍标准差,加个mult = 1参数。 - 按多因子分组:在
aes里通过group或者直接用colour/fill绑定因子,就能自动按因子水平分组计算统计量。 - 优化可视化效果:调整点的透明度、线条样式,避免重叠混乱。
优化后的代码示例:
library(ggplot2) library(tidyquant) # 用于theme_tq() df %>% ggplot(aes(x = Step, y = BDV, colour = Measurement_type, group = Measurement_type)) + # 标准差填充区域,半透明填充 stat_summary(fun.data = mean_sdl, mult = 1, geom = "ribbon", alpha = 0.2, colour = NA, fill = "grey50") + # 均值线,用粗线条区分 stat_summary(fun = mean, geom = "line", linewidth = 1.2) + # 原始数据点,添加透明度避免重叠,保留Rep的形状区分 geom_point(aes(shape = Rep), size = 3, alpha = 0.6) + xlab("Step") + ylab("BDV / kV") + theme_tq()
如果需要按多个因子组合分组(比如同时按Measurement_type和Pollution),只需要修改aes里的分组和颜色映射:
df %>% ggplot(aes(x = Step, y = BDV, colour = interaction(Measurement_type, Pollution), group = interaction(Measurement_type, Pollution), fill = interaction(Measurement_type, Pollution))) + stat_summary(fun.data = mean_sdl, mult = 1, geom = "ribbon", alpha = 0.2, colour = NA) + stat_summary(fun = mean, geom = "line", linewidth = 1.2) + geom_point(aes(shape = Rep), size = 3, alpha = 0.6) + xlab("Step") + ylab("BDV / kV") + labs(colour = "Group", fill = "Group") + # 修改图例标题 theme_tq()
注意点:
stat_summary会自动按aes里的group分组计算统计量,不需要手动预处理数据。- 填充区域用
colour = NA可以去掉边框,避免和均值线重叠。 - 调整
alpha参数让点和填充区域更通透,提升可读性。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

