ggplot散点图颜色参数失效:非异常值出现灰色点问题排查
散点图非异常值显示灰色的问题排查
问题背景
循环创建系列散点图,Y轴为count difference,X轴为sample。定义差异超过10%的样本为异常值(红色),其余为非异常值(绿色),但实际部分非异常值显示为灰色(推测是difference=0的点)。
原代码
图表创建循环
myplots <- list() for (x in c(1:length(stage2))) { message(stage2[x]) myplots[[stage2[x]]] <- local({ x <- x perc_diff <- (abs(df[, paste0("D_", stage2[x])])/ (df[, paste0("M_", stage2[x])] + df[ , paste0("H_", stage2[x])])/2)*100 sct <- ggplot(df, aes(x=sample, y= df[, paste0("D_", stage2[x])])) + geom_point(df, size= 2.2, mapping = aes(colour = ifelse(perc_diff >= 10 , "outlier", "non-outlier"))) + labs(y = "", x= "") + theme(axis.text.x = element_blank(), axis.ticks.x=element_blank(), legend.position = "none") + scale_color_manual(values=c("palegreen3", "tomato3")) print(sct) }) }
标题添加与排列
for (i in c(1:length(D_stage))){ myplots[[i]] <- myplots[[i]] + ggtitle((stage2[i])) + theme(plot.title = element_text(size = 25)) } gridExtra::grid.arrange(grobs = myplots, ncol = 2, left = "count difference", bottom = "sample")
错误原因
- NA值导致灰色点:当
M_xxx和H_xxx的和为0时,计算perc_diff的分母为0,会生成NA值。ifelse遇到NA时返回NA,而scale_color_manual未定义NA对应的颜色,ggplot会用默认灰色显示这些点。 - 代码冗余:
geom_point中重复传入df属于多余操作,ggplot会从主图层继承数据。 - 索引写法不规范:直接用
df[, ...]的方式在aes中引用列,不符合ggplot的最佳实践。
修正后的代码
图表创建循环
myplots <- list() for (x in seq_along(stage2)) { message(stage2[x]) myplots[[stage2[x]]] <- local({ current_stage <- stage2[x] # 计算百分比差异,处理分母为0的情况 numerator <- abs(df[[paste0("D_", current_stage)]]) denominator <- (df[[paste0("M_", current_stage)]] + df[[paste0("H_", current_stage)]])/2 perc_diff <- ifelse(denominator == 0, 0, (numerator / denominator) * 100) # 定义分组,确保无NA point_group <- ifelse(perc_diff >= 10, "outlier", "non-outlier") sct <- ggplot(df, aes(x = sample, y = .data[[paste0("D_", current_stage)]])) + geom_point(size = 2.2, aes(colour = point_group)) + labs(y = "", x = "") + theme(axis.text.x = element_blank(), axis.ticks.x = element_blank(), legend.position = "none") + scale_color_manual(values = c("non-outlier" = "palegreen3", "outlier" = "tomato3")) print(sct) }) }
标题添加与排列
for (i in seq_along(D_stage)){ myplots[[i]] <- myplots[[i]] + ggtitle(stage2[i]) + theme(plot.title = element_text(size = 25)) } gridExtra::grid.arrange(grobs = myplots, ncol = 2, left = "count difference", bottom = "sample")
关键修正点
- 处理分母为0的情况:当
M和H的和为0时,直接将perc_diff设为0,确保point_group不会出现NA - 显式指定
scale_color_manual的颜色映射,避免顺序匹配错误 - 使用
.data[[...]]规范引用列名,符合ggplot语法 - 移除
geom_point中多余的df参数 - 用
seq_along替代1:length(),更安全的循环索引方式
内容的提问来源于stack exchange,提问作者Juju
相关产品推荐
相关产品推荐

