合并tileplot与dendrogram时,如何对齐Y轴元素并调整树状图尺寸?
解决Tile图与树状图合并后Y轴标签对齐问题
问题背景
需要将tile对象生成的tileplot与dendro对象生成的dendrogram合并,同时固定Y轴所有元素的位置,但使用ggarrange合并后,树状图的Y轴尺寸过长,导致标签无法对应层级,且默认heatmap()函数无法满足展示需求。
解决方案
核心思路是让两个图的Y轴范围完全匹配,同时通过对齐参数和布局调整确保标签层级对应。以下是具体实现步骤:
1. 确保Y轴因子顺序一致
先保证tile图的Y轴因子顺序与树状图的叶子节点顺序完全匹配(已完成的代码保留):
library(tidyverse) library(dendextend) library(ggpubr) library(ggdendro) df <- tibble( Method=c("kbest_f","fpr_chi2","perc_f","kbest_chi2","fpr_chi2","perc_mutual","perc_f","perc_mutual","fpr_chi2","fpr_chi2"), Coincidence = c("AVV","ENH","MPN","WET","TKR","LEA","SPQ","PIY","VYL","AGL"), n=rep(1,10)) scores <- with(df, table(Coincidence, Method)) dendro <- as.dendrogram(hclust(dist(scores, method="binary"), method="ward.D")) tile <- df %>% mutate(Coincidence = factor(Coincidence,levels=partition_leaves(dendro)[[1]]))
2. 生成对齐后的Tile图和树状图
修改tile图和树状图的代码,确保Y轴范围一致并调整布局:
# 生成Tile图,调整主题去掉多余元素 tileplot <- tile %>% ggplot(aes(Method, Coincidence, fill= n)) + geom_tile()+ theme( axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1), axis.text.y = element_text(size=5), legend.position="none", axis.title.y = element_blank(), # 去掉Y轴标题避免重复 plot.margin = margin(0, 0, 0, 0) ) # 手动提取树状图数据,映射叶子节点到Tile图的Y轴位置 dendro_data <- dendro_data(dendro, type = "rectangle") # 将树状图叶子节点的Y坐标匹配到Tile图的因子顺序 leaf_y <- match(dendro_data$labels$label, levels(tile$Coincidence)) dendro_data$labels$y <- leaf_y # 调整树状图线段数据,确保结构适配Tile图Y轴范围 dendro_data$segments <- dendro_data$segments %>% mutate( y = ifelse(y %in% dendro_data$labels$y, y, y), yend = ifelse(yend %in% dendro_data$labels$y, yend, yend) ) # 绘制对齐后的树状图 dendroplot <- 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), size = 5/.pt, vjust = 0.5, hjust = 1.0) + coord_flip() + # 设置Y轴范围与Tile图完全一致 scale_y_continuous(limits = c(0.5, length(levels(tile$Coincidence)) + 0.5)) + theme( axis.text.y = element_blank(), # 去掉树状图Y轴文本,复用Tile图的标签 axis.title.y = element_blank(), axis.text.x = element_blank(), axis.title.x = element_blank(), axis.ticks = element_blank(), plot.margin = margin(0, 0, 0, 0) )
3. 合并并对齐两个图
使用ggarrange的垂直对齐参数,同时调整宽度比例让树状图更紧凑:
ggarrange( tileplot, dendroplot, labels=c("A","B"), ncol=2, nrow=1, align = "v", # 垂直对齐Y轴 widths = c(4, 1) # 调整两个图的宽度比例 )
关键说明
- 手动映射树状图叶子节点的Y坐标,确保每个标签与Tile图的因子位置完全对应;
- 设置一致的Y轴范围,避免两个图的Y轴缩放差异;
- 调整
widths参数控制树状图的宽度,避免其占用过多空间; - 使用
align="v"确保两个图的Y轴完全对齐,消除偏移。
内容的提问来源于stack exchange,提问作者Adonis Cedeño
相关产品推荐
相关产品推荐

