如何在R基础绘图中为矩阵散点图按因子着色?
R基础绘图矩阵散点图着色问题(含NA值处理)
我需要对比多个变量,尝试用R基础绘图绘制矩阵散点图,但遇到两个问题:
- 切换到R基础绘图后,数据点着色编码失效,和ggplot2的显示结果不一致
- 数据包含NA值,去除NA后,着色编码再次变化,导致前后两幅基础绘图无法对比
怀疑问题和因子处理有关,但无法解决,以下是可复现代码:
library("scales") library("ggplot2") # 加载并子集化数据简化绘图 part_iris <- iris[c(1:10, 51:60, 101:110), ] # 选择要绘制的变量 params_to_plot <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width") # 设置因子水平 part_iris$Species <- factor(part_iris$Species, levels=c("setosa", "virginica", "versicolor")) # 设置随机种子生成NA值 set.seed(131) # 为各变量随机设置NA part_iris[sample(1:nrow(part_iris), 5), "Sepal.Length"] <- NA part_iris[sample(1:nrow(part_iris), 5), "Sepal.Width"] <- NA part_iris[sample(1:nrow(part_iris), 5), "Petal.Length"] <- NA part_iris[sample(1:nrow(part_iris), 5), "Petal.Width"] <- NA # 创建物种对应的调色板(原代码此处存在拼写错误:viriginica → virginica) species_palette <- hue_pal()(3) names(species_palette) <- c("setosa", "virginica", "versicolor") # ggplot参考绘图(用于对比颜色) dev.new() ggplot(part_iris, aes(x=Sepal.Length, y=Petal.Width, color=Species)) + geom_point(size=5) # 原基础绘图(着色失效) dev.new() plot(part_iris[, params_to_plot], pch=21, cex=3, col="black", bg=species_palette, cex.axis=2, font=2) legend(x="topright", legend=names(species_palette), col=species_palette, pch=21, xpd=T, ncol=3) # 去除NA值 no_nas_iris <- part_iris[complete.cases(part_iris), ] # ggplot参考绘图(去除NA后) dev.new() ggplot(no_nas_iris, aes(x=Sepal.Length, y=Petal.Width, color=Species)) + geom_point(size=5) # 原基础绘图(去除NA后着色变化) dev.new() plot(no_nas_iris[, params_to_plot], pch=21, cex=3, col="black", bg=species_palette, cex.axis=2, font=2) legend(x="topright", legend=names(species_palette), col=species_palette, pch=21, xpd=T, ncol=3)
问题原因与解决方法
1. 着色失效的核心原因
原代码中bg=species_palette直接传入长度为3的颜色向量,R基础绘图会循环使用该向量为每个点着色,没有和每个数据点的Species做对应匹配。此外,原代码中species_palette的名称存在拼写错误(viriginica少了字母g),导致即使尝试匹配也会失败。
2. 修正后的着色逻辑
要让每个点的颜色对应其所属物种,需根据每行的Species取值,从species_palette中提取对应颜色,用bg = species_palette[as.character(数据框$Species)]实现。
3. 去除NA后的颜色一致性
去除NA后的数据行顺序会变化,但只要保持颜色和Species的对应关系,就能保证前后绘图的颜色一致,无需额外调整因子。
修正后的完整代码
library("scales") library("ggplot2") part_iris <- iris[c(1:10, 51:60, 101:110), ] params_to_plot <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width") part_iris$Species <- factor(part_iris$Species, levels=c("setosa", "virginica", "versicolor")) set.seed(131) part_iris[sample(1:nrow(part_iris), 5), "Sepal.Length"] <- NA part_iris[sample(1:nrow(part_iris), 5), "Sepal.Width"] <- NA part_iris[sample(1:nrow(part_iris), 5), "Petal.Length"] <- NA part_iris[sample(1:nrow(part_iris), 5), "Petal.Width"] <- NA # 修正拼写错误的调色板名称 species_palette <- hue_pal()(3) names(species_palette) <- c("setosa", "virginica", "versicolor") # ggplot参考绘图 dev.new() ggplot(part_iris, aes(x=Sepal.Length, y=Petal.Width, color=Species)) + geom_point(size=5) # 修正后的基础绘图:按Species匹配颜色 dev.new() plot(part_iris[, params_to_plot], pch=21, cex=3, col="black", bg=species_palette[as.character(part_iris$Species)], # 核心修正 cex.axis=2, font=2) legend(x="topright", legend=names(species_palette), col=species_palette, pch=21, xpd=T, ncol=3) # 去除NA值 no_nas_iris <- part_iris[complete.cases(part_iris), ] # ggplot参考绘图(去除NA后) dev.new() ggplot(no_nas_iris, aes(x=Sepal.Length, y=Petal.Width, color=Species)) + geom_point(size=5) # 修正后的基础绘图(去除NA后) dev.new() plot(no_nas_iris[, params_to_plot], pch=21, cex=3, col="black", bg=species_palette[as.character(no_nas_iris$Species)], # 保持对应关系 cex.axis=2, font=2) legend(x="topright", legend=names(species_palette), col=species_palette, pch=21, xpd=T, ncol=3)
内容的提问来源于stack exchange,提问作者another_rando
相关产品推荐
相关产品推荐

