如何用ggplot2为PCoA分析的样本点正确着色?
PCoA分析中ggplot2点着色问题的解决
问题场景
我基于二进制数据集做PCoA分析,跟着教程完成了距离矩阵构建与PCoA计算,但在ggplot2绘图时遇到点着色异常:
- 已将行名设为样本名,代码中写
color = "samples"时,所有点颜色完全一致,图例显示为“samples”,无法按样本分组区分颜色。 - 尝试教程里的
inner_join方法合并数据但未成功,最终通过重新整理PCoA结果为数据框并手动分配分组信息,实现了按分组着色。
错误代码分析
原始出错的核心代码片段:
positions %>% as_tibble(rownames="samples") %>% ggplot(aes(x=pcoa1, y=pcoa2, color = "samples")) + geom_point() + labs(x=labs[1], y=labs[2])
错误原因:color = "samples"是传入字符串常量,ggplot会将其视为单一分组值,导致所有点用同一种颜色。正确写法应引用数据框中名为samples的列(或分组列),需去掉引号写成color = samples,且前提是数据中包含对应分组信息。
解决思路与修正代码
核心是将PCoA坐标数据与样本分组信息合并到同一数据框,让ggplot读取分组列实现着色。
完整修正代码
# 1. 构建二进制距离矩阵 cal_fem_dist <- dist(cfd, method = "binary") cal_fem_dist2 <- as.matrix(cal_fem_dist) # 2. 执行PCoA分析 pcoa_cf <- cmdscale(cal_fem_dist2, eig=T, add=T) positions <- pcoa_cf$points colnames(positions) <- c("pcoa1", "pcoa2") # 3. 计算轴标签的解释度 percent_explained <- 100 * pcoa_cf$eig / sum(pcoa_cf$eig) pretty_pe <- round(percent_explained[1:2], digits = 1) labs <- c(glue("PCo 1 ({pretty_pe[1]}%)"), glue("PCo 2 ({pretty_pe[2]}%)")) # 4. 合并PCoA坐标与分组数据 # 假设cal_fem_data2包含样本行名和分组列(示例列名为group) pcoa_df <- as_tibble(positions, rownames = "samples") %>% inner_join(as_tibble(cal_fem_data2, rownames = "samples"), by = "samples") # 5. ggplot2按分组着色绘图 ggplot(pcoa_df, aes(x=pcoa1, y=pcoa2, color = group)) + geom_point(size = 2) + labs(x=labs[1], y=labs[2], color = "分组") + theme_bw()
关键修正说明
- 合并数据前需确保两个数据框的样本名字段完全匹配(无大小写、空格、后缀差异),这是
inner_join失败的常见原因。 - 绘图时
color = group中的group需替换为你实际的分组列名,且不能加引号,让ggplot识别为数据框列。
内容的提问来源于stack exchange,提问作者cassbarker_za
相关产品推荐
相关产品推荐

