ggplot绘图:解决误差线穿透空心散点的问题
问题
使用ggplot绘制带散点与误差棒的图表,需求如下:
- 用颜色区分
treatment变量 - 用实心/空心点区分
trend变量(trend对应lambda是否大于1) - 避免误差线穿透散点
尝试两种方案均未成功:
- 手动设置
fill和col刻度,但未达到预期效果:
plot1 <- ggplot(data = dat, aes(x = species, y = lambda, col = treatment, fill = trend)) + geom_abline(intercept = 1, slope = 0, linetype = "dashed") + geom_errorbar(aes(ymin = lower_BCPI_red, ymax = upper_BCPI_red), width = 0.2, position = position_dodge(width = 0.7)) + geom_point(position = position_dodge(width = 0.7), size = 4) + scale_color_manual( values = c("darkblue", "darkgreen"), labels = c("treat1" = "Treatment 1", "treat2" = "Treatment 2"), guide = guide_legend(order = 1)) + scale_fill_manual( values = c("white", "darkgreen"), labels = c("grow" = expression(paste(lambda, " > 1")), "shrink" = expression(paste(lambda, " < 1"))), guide = guide_legend(order = 2))
- 用形状区分
trend变量,但空心形状(21)会被误差线穿透;尝试叠加白色点遮挡,但因position_dodge未对齐失效:
plot2 <- ggplot(data = dat, aes(x = species, y = lambda, col = treatment, shape = trend)) + geom_abline(intercept = 1, slope = 0, linetype = "dashed") + geom_errorbar(aes(ymin = lower_BCPI_red, ymax = upper_BCPI_red), width = 0.2, position = position_dodge(width = 0.7)) + geom_point(position = position_dodge(width = 0.7), size = 4, col = "white", fill = "white") + geom_point(position = position_dodge(width = 0.7), size = 4) + scale_color_manual( values = c("darkblue", "darkgreen"), labels = c("treat1" = "Treatment 1", "treat2" = "Treatment 2"), guide = guide_legend(order = 1)) + scale_shape_manual( values = c(19, 21), labels = c("grow" = expression(paste(lambda, " > 1")), "shrink" = expression(paste(lambda, " < 1"))), guide = guide_legend(order = 2))
数据:
dat <- structure(list(species = c("spec2", "spec2", "spec1", "spec1" ), treatment = c("treat2", "treat1", "treat2", "treat1"), trend = c("grow", "grow", "grow", "shrink"), lambda = c(2.93041381166779, 2.02556855849611, 1.26209237527084, 0.983136908926705), lower_BCPI_red = c(2.23364635527003, 1.08955927540168, 1.02410220209615, 0.917503038357754), upper_BCPI_red = c(3.87343015758682, 5.08404412887266, 1.40109042463976, 0.998656722552173)), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"))
解决方案
核心思路:
- 使用支持填充的形状:用实心形状(19)对应
lambda>1(trend=grow),用可填充的空心形状(21)对应lambda<1(trend=shrink) - 统一
position_dodge参数,避免图层对齐偏差 - 为空心形状设置白色填充,遮挡下方的误差线
完整代码:
# 统一定义dodge位置,避免对齐问题 pos_dodge <- position_dodge(width = 0.7) ggplot(dat, aes(x = species, y = lambda, color = treatment)) + # 添加lambda=1的参考线 geom_abline(intercept = 1, slope = 0, linetype = "dashed") + # 绘制误差棒,使用统一的dodge位置 geom_errorbar(aes(ymin = lower_BCPI_red, ymax = upper_BCPI_red), width = 0.2, position = pos_dodge) + # 绘制散点:shape映射trend,fill设为白色(仅对空心形状生效) geom_point(aes(shape = trend), size = 4, position = pos_dodge, fill = "white") + # 设置treatment的颜色映射 scale_color_manual( values = c("darkblue", "darkgreen"), labels = c("treat1" = "处理1", "treat2" = "处理2"), guide = guide_legend(order = 1) ) + # 设置trend的形状映射:grow用实心19,shrink用空心21 scale_shape_manual( values = c(grow = 19, shrink = 21), labels = c(grow = expression(lambda > 1), shrink = expression(lambda < 1)), guide = guide_legend(order = 2) )
效果说明
trend=grow(lambda>1):实心点,颜色与对应treatment一致trend=shrink(lambda<1):空心点,边框颜色与对应treatment一致,内部白色填充遮挡住下方的误差线- 所有图层使用统一的
pos_dodge,确保散点与误差棒完全对齐
内容的提问来源于stack exchange,提问作者Em Laskey
相关产品推荐
相关产品推荐

