You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Fviz_PCA_biplot中添加HCPC聚类的凸包边界?

在PCA双标图中添加HCPC聚类的凸包线条

问题背景

已通过fviz_pca_biplot绘制PCA双标图,代码如下:

ph <- "Physiological"
ag <- "Morphological"
trait <- factor(c(ph,ph,ph,ph,ph,ph,ph,ph,ph,ph,ph,ag,ag,ag,ag))

fviz_pca_biplot(pc1, geom.ind = c("text","point"), labelsize = 5,
                pointshape = 22,pointsize = 3,font.family = "serif",
                fill.ind = ct$Species,
                col.ind = "black",
                col.var = trait, 
                repel = T, parse = T,
                legend.title = list(fill = "Species", color = "Traits"))+
  coord_cartesian(xlim = c(-4.5, 4.25), ylim = c(-3,3.5))+
  scale_y_continuous(breaks=c(-3,-2,-1,0,1.25,2.5,3.5),
                     labels = number_format(accuracy = 0.01))+
  scale_x_continuous(breaks=c(-4.75,-3,-1.5,0,1.5,3,4.5))+
  fill_palette(c("#E5871A","#1AE522", "#1A78E5","#E51ADD"))+ 
  color_palette(c("darkgreen", "#1A0DB6"))+
  theme_minimal() + 
  theme(panel.background = element_rect(colour = "black"),
        axis.text.x =element_text(colour="black", size = 9, family = "serif", face = "bold"),
        axis.text.y =element_text(colour="black", size = 9, family = "serif", face = "bold"),
        axis.title = element_text(face = "bold",family = "serif",colour = "black",size = 9),
        plot.title =element_text(vjust = -9,hjust=0.01,face = "bold",family = "sans", size = 10),
        axis.ticks = element_line(colour = "black"),
        legend.position = "right",
        legend.text = element_text(size = 9,face="bold.italic",family = "serif"),
        panel.grid.minor = element_blank()) +
  labs(title = "a.", x= "PC1 (32.49%)", y= "PC2 (21.51%)")

同时通过HCPC完成聚类:

HCPC(pc1, method = "ward", metric= "euclidean", graph=T, order = T)

需求是在上述PCA双标图中添加聚类的凸包线条(连接同聚类个体)。

解决方案

步骤1:保存HCPC聚类结果并提取标签

先关闭自动绘图,保存聚类结果以便后续调用:

# 保存HCPC聚类结果,关闭自动绘图
hcpc_result <- HCPC(pc1, method = "ward", metric= "euclidean", graph=F, order = T)

# 提取个体PCA得分及聚类标签
pca_scores <- as.data.frame(hcpc_result$data.clust[, c("Dim.1", "Dim.2", "clust")])
# 重命名列名以匹配PCA图坐标轴
colnames(pca_scores) <- c("PC1", "PC2", "cluster")

步骤2:计算每个聚类的凸包坐标

使用chull函数计算每个聚类的凸包顶点:

# 定义计算凸包的函数
get_convex_hull <- function(data) {
  data[chull(data$PC1, data$PC2), ]
}

# 按聚类分组生成凸包数据
library(dplyr) # 需要加载dplyr用于分组操作
hull_data <- pca_scores %>%
  group_by(cluster) %>%
  do(get_convex_hull(.))

步骤3:在原有PCA图中添加凸包图层

将原有PCA图保存为对象,再通过geom_polygon添加凸包:

# 保存原有PCA双标图
p_plot <- fviz_pca_biplot(pc1, geom.ind = c("text","point"), labelsize = 5,
                pointshape = 22,pointsize = 3,font.family = "serif",
                fill.ind = ct$Species,
                col.ind = "black",
                col.var = trait, 
                repel = T, parse = T,
                legend.title = list(fill = "Species", color = "Traits"))+
  coord_cartesian(xlim = c(-4.5, 4.25), ylim = c(-3,3.5))+
  scale_y_continuous(breaks=c(-3,-2,-1,0,1.25,2.5,3.5),
                     labels = number_format(accuracy = 0.01))+
  scale_x_continuous(breaks=c(-4.75,-3,-1.5,0,1.5,3,4.5))+
  fill_palette(c("#E5871A","#1AE522", "#1A78E5","#E51ADD"))+ 
  color_palette(c("darkgreen", "#1A0DB6"))+
  theme_minimal() + 
  theme(panel.background = element_rect(colour = "black"),
        axis.text.x =element_text(colour="black", size = 9, family = "serif", face = "bold"),
        axis.text.y =element_text(colour="black", size = 9, family = "serif", face = "bold"),
        axis.title = element_text(face = "bold",family = "serif",colour = "black",size = 9),
        plot.title =element_text(vjust = -9,hjust=0.01,face = "bold",family = "sans", size = 10),
        axis.ticks = element_line(colour = "black"),
        legend.position = "right",
        legend.text = element_text(size = 9,face="bold.italic",family = "serif"),
        panel.grid.minor = element_blank()) +
  labs(title = "a.", x= "PC1 (32.49%)", y= "PC2 (21.51%)")

# 添加凸包图层,设置透明度避免遮挡元素
p_plot +
  geom_polygon(data = hull_data, aes(x = PC1, y = PC2, group = cluster, fill = factor(cluster)),
               alpha = 0.2, colour = "black", show.legend = FALSE)

自定义调整

  • 若要修改凸包填充色,可添加scale_fill_manual(values = c("#颜色1", "#颜色2", ...))
  • 调整alpha值可改变凸包透明度,数值越大越不透明
  • 修改colour参数可调整凸包边框颜色

内容的提问来源于stack exchange,提问作者Ikram Bashir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 21:56:10