如何在ggplot2带层次聚类树的百分比堆叠柱状图中添加分类变量
解决方法
1. 准备示例数据&加载依赖包
先定义符合你场景的简化数据集,同时加载需要的R包:
library(ggplot2) library(ggdendro) library(dplyr) library(tidyr) library(patchwork) # 示例数据集:患者1、3为HIV+,患者2为HIV- sample_data <- data.frame( Sample = c("患者1", "患者2", "患者3"), HIV_Status = factor(c("HIV+", "HIV-", "HIV+")), CellType_A = c(30, 50, 25), CellType_B = c(40, 30, 45), CellType_C = c(30, 20, 30) ) # 转换为堆叠柱状图需要的长格式 long_data <- pivot_longer(sample_data, cols = starts_with("CellType"), names_to = "CellType", values_to = "Percentage")
2. 生成层次聚类树并关联样本信息
计算聚类后,提取树的绘图数据,同时把HIV状态关联到树的节点上:
# 提取聚类用的数值矩阵 cluster_matrix <- sample_data %>% select(starts_with("CellType")) %>% as.matrix() rownames(cluster_matrix) <- sample_data$Sample # 计算层次聚类 hc <- hclust(dist(cluster_matrix)) # 提取树的绘图数据,关联HIV状态 dendro_data <- dendro_data(hc, type = "rectangle") node_info <- dendro_data$labels %>% left_join(sample_data %>% select(Sample, HIV_Status), by = c("label" = "Sample"))
3. 绘制带样本名称的聚类树
添加样本名称到树的节点旁(优先级低的需求),调整参数避免标签重叠:
p_dendro <- ggplot() + # 绘制树的分支 geom_segment(data = dendro_data$segments, aes(x = x, y = y, xend = xend, yend = yend)) + # 添加样本名称 geom_text(data = dendro_data$labels, aes(x = x, y = y, label = label), hjust = -0.1, size = 3) + theme_dendro() + coord_flip() + ylim(-5, max(dendro_data$segments$y) + 10) # 预留标签空间
4. 绘制关联HIV状态的堆叠柱状图
这里提供两种方式关联HIV分类颜色:
方式1:柱子边框对应HIV状态颜色
# 按聚类顺序排序样本 sample_order <- dendro_data$labels$label long_data$Sample <- factor(long_data$Sample, levels = sample_order) p_bar <- ggplot(long_data %>% left_join(sample_data), aes(x = Sample, y = Percentage, fill = CellType)) + geom_col(position = "fill", aes(color = HIV_Status), linewidth = 1.2) + scale_y_continuous(labels = scales::percent) + scale_color_manual(values = c("HIV+" = "#e74c3c", "HIV-" = "#3498db")) + scale_fill_brewer(palette = "Set2") + coord_flip() + theme_minimal() + theme(legend.position = "bottom")
方式2:柱子顶部添加HIV状态颜色标记
p_bar <- ggplot(long_data, aes(x = Sample, y = Percentage, fill = CellType)) + geom_col(position = "fill", color = "black") + # 在柱子顶部添加对应HIV状态的颜色点 geom_point(data = sample_data, aes(x = Sample, y = 1.1, color = HIV_Status), size = 5) + scale_y_continuous(labels = scales::percent, limits = c(0, 1.2)) + scale_color_manual(values = c("HIV+" = "#e74c3c", "HIV-" = "#3498db")) + scale_fill_brewer(palette = "Set2") + coord_flip() + theme_minimal() + theme(legend.position = "bottom")
5. 拼接聚类树与柱状图
用patchwork包将两个图拼接,调整宽度比例适配显示:
p_dendro + p_bar + plot_layout(widths = c(1, 2))
内容的提问来源于stack exchange,提问作者Cooper James
相关产品推荐
相关产品推荐

