如何调整R语言中DoHeatmap绘图的聚类列宽?
优化Seurat DoHeatmap热图列宽与拥挤问题
问题背景
我基于Seurat对象绘制空间转录组数据的标记基因热图,数据处理代码如下:
visium_x22117 = Load10X_Spatial(data.dir = "~/PhD_Project_Moh_Huda/Dataset_files/X22117_Visium_scRNA/", filename = "X22117_filtered_feature_bc_matrix.h5") suppressWarnings({ visium_x22117 = SCTransform(visium_x22117, assay = "Spatial", verbose = FALSE) })
绘制热图的代码:
visium_x22117.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) -> top10 heatmap = DoHeatmap(visium_x22117, features = top10$gene) heatmap
生成的热图存在两个问题:整体布局拥挤,且cluster 0的列宽远大于其他聚类(如图所示)。查阅DoHeatmap文档未找到调整列宽的方法,需要优化该热图。

解决方法
1. 抽样均衡各簇细胞数量(核心解决列宽不均)
DoHeatmap默认按簇内细胞数量比例分配列宽,cluster 0细胞数过多是列宽偏大的原因。通过抽样让每个簇展示相同数量的细胞,既能统一列宽,又能减少总细胞数缓解拥挤:
# 设置随机种子保证结果可重复 set.seed(123) # 每个簇抽取固定数量细胞(示例为50个,可根据实际调整) sampled_cells <- lapply(unique(visium_x22117$seurat_clusters), function(clust) { cluster_cells <- colnames(visium_x22117)[visium_x22117$seurat_clusters == clust] # 如果簇内细胞数不足设置值,就取全部细胞 sample(cluster_cells, size = min(50, length(cluster_cells)), replace = FALSE) }) %>% unlist() # 指定抽样后的细胞绘制热图 heatmap <- DoHeatmap(visium_x22117, features = top10$gene, cells = sampled_cells) heatmap
2. 调整热图样式缓解拥挤
通过ggplot主题调整字体、边距,或指定更大的保存尺寸进一步优化:
heatmap + theme( axis.text.y = element_text(size = 7), # 缩小基因名字体 axis.text.x = element_blank(), # 隐藏底部细胞标签(不需要时) plot.margin = margin(10, 15, 10, 15), # 调整图的边距 legend.key.height = unit(0.4, "cm") # 缩小图例高度 ) + ggtitle("Top 10 Marker Genes per Cluster") + theme(plot.title = element_text(hjust = 0.5, size = 12)) # 保存时指定更大宽度避免拥挤 ggsave("optimized_heatmap.pdf", width = 14, height = 9, dpi = 300)
3. 可选:手动调整列宽(无需抽样)
若不想改变细胞展示数量,可通过修改ggplot对象的底层参数强制统一列宽,需要借助ggplot2的底层元素调整:
# 提取热图的ggplot数据 heatmap_data <- heatmap$data # 为每个簇设置相同的宽度权重 heatmap_data$width <- 1 / length(unique(heatmap_data$cluster)) # 重新构建热图 library(ggplot2) ggplot(heatmap_data, aes(x = cell, y = gene, fill = avg_log2FC)) + geom_tile() + scale_fill_gradientn(colors = c("#3C5488FF", "white", "#DC0000FF")) + facet_grid(~cluster, scales = "free_x", space = "free_x") + theme(axis.text.x = element_blank(), axis.ticks.x = element_blank()) + labs(x = "", y = "Genes", fill = "avg_log2FC")
这种方法需要手动重构热图,灵活性更高,但步骤相对繁琐。
内容的提问来源于stack exchange,提问作者MK Huda
相关产品推荐
相关产品推荐

