ggplot2调整geom_rect与geom_errorbar图层顺序时出现刻度颜色错误
ggplot图层顺序调整引发的离散/连续刻度错误修复
复现数据
electrode <- c('Cz','Fz','Pz') value <- c(2.307785,1.613350,2.925053) sd <- c(0.7593193,0.7612393,0.7568794) se <- c(0.002829816,0.002836971,0.002820723) ci <- c(0.005546431,0.005560455,0.005528609) tgc <- data.frame(electrode,value,sd,se,ci) col <- c("#004d8d", "#cc2701", "#e5b400") stdev <- c(10.783939,10.506721,9.415955)
问题描述
原本在ggplot中使用手动颜色刻度,将geom_errorbar放在geom_rect之前时绘图正常,但灰色遮罩会覆盖中间Fz的误差线和点。为调整图层顺序,调换geom_rect与geom_errorbar的位置后运行以下代码:
p1 <- ggplot(tgc, aes(x=factor(electrode), y=value, colour=electrode)) + geom_rect(inherit.aes = FALSE,mapping =aes(xmin=0, xmax=Inf, ymin=-0.1*min(stdev), ymax=0.1*max(stdev)),fill="grey",alpha = 0.5) + geom_errorbar(aes(ymin=value-sd, ymax=value+sd), width=.1, alpha=.5) + scale_color_manual(values = col, breaks = c("Fz", "Cz", "Pz")) + scale_fill_manual(values = col, breaks = c("Fz", "Cz", "Pz")) + labs(title="Difference at max. discrepancy", x="Electrode", y="Signal (µV)") + lims(y = c(-10, 10)) + theme_linedraw() + geom_point() p1
出现错误:Error: Discrete value supplied to continuous scale,无法生成绘图。已在geom_rect中指定fill参数,询问操作错误点。
错误原因与修复方案
错误根源
- 多余的
scale_fill_manual:你全局添加了针对离散electrode变量的fill刻度,但geom_rect是手动指定fill="grey",并没有映射离散fill变量,导致ggplot试图将离散刻度应用到非离散的fill值上,触发类型冲突。 - 离散x轴的连续范围设置:
geom_rect中xmin=0和xmax=Inf是连续值,而x轴是离散的factor(electrode),两者类型不兼容,进一步加剧了刻度冲突。
修正代码
p1 <- ggplot(tgc, aes(x=factor(electrode), y=value, colour=electrode)) + # 调整x范围适配离散轴,移除多余的aes映射 geom_rect(inherit.aes = FALSE, xmin=0.5, xmax=3.5, ymin=-0.1*min(stdev), ymax=0.1*max(stdev), fill="grey", alpha = 0.5) + geom_errorbar(aes(ymin=value-sd, ymax=value+sd), width=.1, alpha=.5) + scale_color_manual(values = col, breaks = c("Fz", "Cz", "Pz")) + labs(title="Difference at max. discrepancy", x="Electrode", y="Signal (µV)") + lims(y = c(-10, 10)) + theme_linedraw() + geom_point() p1
修正说明
- 移除
scale_fill_manual:既然没有图层需要基于离散变量映射fill颜色,这个刻度完全没必要存在,去掉后即可解决离散/连续刻度冲突问题。 - 调整
geom_rect的x范围:离散轴的每个类别对应一个整数位置(1=Cz,2=Fz,3=Pz),设置xmin=0.5和xmax=3.5可以让灰色遮罩刚好覆盖所有电极的横向范围,同时不会和离散轴的刻度类型冲突。 - 图层顺序调整后,灰色遮罩会绘制在最底层,不会覆盖后续的误差线和点,实现预期效果。
内容的提问来源于stack exchange,提问作者Unai Vicente
相关产品推荐
相关产品推荐

