R语言树状图:添加自定义文本与分支按聚类着色问题
问题1:用dendextend添加自定义副标题/脚注
dendextend基于R基础绘图系统,绘制树状图后直接用mtext()函数就能添加脚注或副标题,操作简单直接。示例代码如下:
hc <- hclust(dist_s, method = 'average') dend = as.dendrogram(hc) # 调大底部边距,避免脚注被截断 par(mar = c(5, 2, 2, 8)) dend %>% set("labels_cex", 0.9) %>% set("branches_k_color", value = c("#E69F00", "#56B4E9", "#009E73"), k = 3) %>% plot(main = "Hierarchical clustering", horiz= TRUE) # 添加自定义脚注:side=1表示底部,line控制与绘图区的距离,cex调整字号 mtext("脚注说明:样本1属于聚类1,样本2-3属于聚类2,样本4-7属于聚类3", side = 1, line = 3, cex = 0.8, col = "darkgray")
- 调整
par(mar)的第一个参数(底部边距数值),确保脚注有足够显示空间; mtext的side参数可选1(下)、2(左)、3(上)、4(右),按需调整文本位置。
问题2:ggplot2中正确将分支颜色映射到聚类分配
你之前的错误根源是:dend_data$segments是所有分支线段的数据集(行数远多于样本数),直接把样本级的clusters向量赋值过去必然出现行数不匹配。正确做法是先给 dendrogram 绑定聚类颜色信息,再转成ggplot可用的数据结构:
步骤1:关联聚类信息到 dendrogram
用dendextend的color_branches_by_labels_groups函数,把样本聚类信息传递到对应的分支上:
hc <- hclust(dist_s, method = 'average') # 替换成你的聚类分配向量(比如clust_df$cluster) clusters <- clust_df$cluster # 对应聚类的颜色映射 cluster_colors <- c("#E69F00", "#56B4E9", "#009E73") # 给dendrogram标记分支颜色 dend <- as.dendrogram(hc) %>% color_branches_by_labels_groups(clusters = clusters, groupColors = cluster_colors)
步骤2:转成ggplot数据并绘图
把带颜色信息的dendrogram转成dend_data,然后在ggplot中直接调用分支自带的颜色列:
library(ggplot2) library(dendextend) library(ggdendro) dend_data <- dendro_data(dend, type = "rectangle") # 绘制树状图 ggplot() + geom_segment(data = dend_data$segments, aes(x = x, y = y, xend = xend, yend = yend, color = col)) + geom_text(data = dend_data$labels, aes(x = x, y = y, label = label), hjust = 1, size = 3) + scale_color_identity() # 直接使用dendrogram中预设的颜色值 coord_flip() # 转为水平树状图 labs(title = "Hierarchical clustering", x = "", y = "Distance") + theme_minimal() + theme(axis.text.y = element_blank(), axis.ticks.y = element_blank()) # 添加自定义文本(比如脚注) annotate("text", x = max(dend_data$labels$x) + 1, y = -0.5, label = "自定义说明:聚类1为橙色,聚类2为蓝色,聚类3为绿色", size = 3, color = "darkgray")
关键说明
color_branches_by_labels_groups会自动将样本的聚类信息传递到所属分支,生成的dend对象已包含分支颜色属性;- 转成
dend_data后,segments的col列就是分支的颜色值,用scale_color_identity()可直接映射; - 用
annotate()添加自定义文本,调整x和y参数控制文本位置。
内容的提问来源于stack exchange,提问作者Vitória Stavis
相关产品推荐
相关产品推荐

