ggplot2绘制PCA散点图时图例形状与实际展示不一致问题求解
问题原因
- 核心问题1:你未将形状参数和分组变量
obsnames做美学映射,仅将shape作为geom_point的全局固定参数按行分配形状,ggplot生成fill图例时没有和分组的形状做绑定,仅通过override.aes手动覆盖很容易出现顺序错配。 - 核心问题2:当观测数小于形状向量长度(5)时,
rep_len取前N个形状的顺序,若和obsnames的因子水平排序不完全匹配,就会出现图例和实际点样式不一致的问题,观测数等于5时刚好顺序对齐,所以问题消失。 - 额外语法问题:你原代码中
rep_len(c(21, 22, 23, 24, 25) length.out = len)缺了一个逗号,会直接导致语法报错,运行前需要修正。
解决方法
直接将形状也映射到obsnames变量,通过scale_shape_manual指定形状序列,不需要额外用guide_legend的override.aes修改图例,即可保证图中点和图例样式完全匹配,修改后代码如下:
len <- length(pca_data$obsnames) # 手动指定obsnames的因子顺序,保证和你预期的颜色、形状顺序一致 pca_data$obsnames <- factor(pca_data$obsnames, levels = pca_data$obsnames) ggplot(pca_data, aes_string(x=x, y=y)) + # 将shape也放入aes中映射到分组变量 geom_point(aes(fill=obsnames, shape=obsnames), color = "black", size = 3) + theme_bw() + theme(legend.position="right") + xlab(label_x) + ylab(label_y) + ggtitle(main) + theme(plot.title = element_text(hjust = 0, face="bold")) + # 删除冗余的aes映射,避免不必要的警告 geom_hline(yintercept=0, size=.2) + geom_vline(xintercept=0, size=.2) + coord_equal() + geom_text(data=datapc, aes(x=v1, y=v2, label=varnames), size = 3, vjust=0.3, color="grey", fontface="bold") + geom_segment(data=datapc, aes(x=0, y=0, xend=v1, yend=v2), color="grey", linetype="dotted") + scale_fill_manual(values = rep_len(c("red", "blue", "green", "orange", "yellow", "purple", "pink", "light blue", "white", "black", "gold"), length.out = len)) + # 新增手动指定形状的缩放配置,自动和分组绑定 scale_shape_manual(values = rep_len(c(21,22,23,24,25), length.out = len))
内容的提问来源于stack exchange,提问作者John Sandman
相关产品推荐
相关产品推荐

