如何解决ggplot中转换因子后误差栏重复显示的问题?
问题
原本绘图时误差栏显示正常,但x轴顺序混乱(显示为"0""16""32""8"),于是将Well转换为因子:
welldata$Well_f <- factor(welldata$Well, levels = c('0', '8', '16', '32'))
转换后x轴顺序正确,但误差栏不再仅显示在对应Well分组内,而是每个列都重复出现。需求为:在不改变facet_wrap顺序的前提下修复该问题。
当前绘图代码:
ggplot(welldata, aes(x = E2F4, y = Colonies, color = Clone, fill = E2F4)) + geom_point(size = 2) + geom_errorbar(data = error_data, aes(ymin = ymin, ymax = ymax), width = 0.2, color = "black") + labs(title = "HT29 Colony Survival", x = "Concentration of SN-38 (nM)", y = "Number of colonies") + scale_color_manual(values = c('11' = "darkturquoise", "7" = "darkturquoise", "2" = "darkturquoise","Control"= "darkorchid")) + scale_fill_discrete(labels = c("-/- = E2F4 Knockout", "+/+ = E2F4 Wild Type")) + guides(color = guide_legend(override.aes = list(size = 3)), fill = guide_legend(override.aes = list(size = 2))) + facet_wrap(~Well_f, nrow = 1, strip.position = "bottom") + theme_minimal() + theme(strip.placement = "outside", panel.spacing = unit(0, "cm"), strip.text = element_text(size = 10, margin = margin(b = 15)), legend.title = element_text(size = 10), plot.title = element_text(margin = margin(b = 10)))
现象:使用Well作为facet_wrap变量时,误差栏显示正常但x轴顺序混乱;使用Well_f时顺序正确但误差栏重复显示。
数据(welldata)
structure(list(E2F4 = c("+/+", "+/+", "+/+", "-/-", "-/-", "-/-", "-/-", "-/-", "-/-", "-/-", "-/-", "-/-", "+/+", "+/+", "+/+", "+/+", "+/+", "+/+", "-/-", "-/-", "-/-", "-/-", "-/-", "-/-", "-/-", "-/-", "-/-", "+/+", "+/+", "+/+"), Colonies = c(1052, 983, 1057, 497, 464, 437, 111, 81, 85, 40, 42, 43, 523, 523, 636, 646, 730, 749, 58, 60, 53, 705, 746, 785, 54, 82, 80, 1618, 1470, 1505), Clone = c("Control", "Control", "Control", "7", "7", "7", "11", "11", "11", "2", "2", "2", "Control", "Control", "Control", "Control", "Control", "Control", "2", "2", "2", "7", "7", "7", "11", "11", "11", "Control", "Control", "Control"), Well = c("32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32", "32"), Hour = c(24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48), Well_f = structure(c(4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), .Label = c("0", "8", "16", "32"), class = "factor")), row.names = c(NA, -30L ), class = c("tbl_df", "tbl", "data.frame"))
误差数据(error_data)
error_data <- data.frame( E2F4 = c("-/-", "+/+", "-/-", "+/+", "-/-", "+/+", "-/-", "+/+"), Colonies = c(2837.3333, 1911.33333, 137, 259.6667, 95.666, 557.6667, 74.333, 757.3333), Well = c("0", "0", "8", "8", "16", "16", "32", "32"), Errors = c(334.02993877795, 103.568010, 158.745, 197.616630, 93.0931, 133.82949, 66.515, 43.98106)) error_data <- error_data %>% mutate(ymin = Colonies - Errors, ymax = Colonies + Errors)
解决方案
问题原因
误差栏重复显示是因为error_data中没有对应的Well_f因子列,ggplot无法将误差数据与分面的Well_f匹配,导致每个分面都加载了所有误差数据。
修复步骤
- 给
error_data添加Well_f因子列,与welldata的因子规则保持一致:
error_data$Well_f <- factor(error_data$Well, levels = c('0', '8', '16', '32'))
- 确保
geom_errorbar的误差数据与主数据的分面变量对齐,ggplot会自动匹配分面变量,仅加载对应分组的误差数据。
修改后的完整绘图代码
# 先给error_data添加Well_f因子列 error_data$Well_f <- factor(error_data$Well, levels = c('0', '8', '16', '32')) ggplot(welldata, aes(x = E2F4, y = Colonies, color = Clone, fill = E2F4)) + geom_point(size = 2) + # 分面变量已匹配,无需额外指定group geom_errorbar(data = error_data, aes(x = E2F4, ymin = ymin, ymax = ymax), width = 0.2, color = "black") + labs(title = "HT29 Colony Survival", x = "Concentration of SN-38 (nM)", y = "Number of colonies") + scale_color_manual(values = c('11' = "darkturquoise", "7" = "darkturquoise", "2" = "darkturquoise","Control"= "darkorchid")) + scale_fill_discrete(labels = c("-/- = E2F4 Knockout", "+/+ = E2F4 Wild Type")) + guides(color = guide_legend(override.aes = list(size = 3)), fill = guide_legend(override.aes = list(size = 2))) + facet_wrap(~Well_f, nrow = 1, strip.position = "bottom") + theme_minimal() + theme(strip.placement = "outside", panel.spacing = unit(0, "cm"), strip.text = element_text(size = 10, margin = margin(b = 15)), legend.title = element_text(size = 10), plot.title = element_text(margin = margin(b = 10)))
补充说明
若仍出现匹配问题,在geom_errorbar的aes中明确指定x = E2F4,可保证每个分面内的误差栏精准对应到E2F4的两个分组,避免重复显示。
内容的提问来源于stack exchange,提问作者astaf
相关产品推荐
相关产品推荐

