基于Python Plotly构建仅含左侧树状图的聚类热图技术实现问询
Python Plotly实现仅左侧带树状图的聚类热图(适配大规模数据)
嘿,我完全get到你的需求了——想要用Python的Plotly做一个只有左侧带Y轴层次聚类树状图的热图,还要能适配120行这种大规模数据,而且不想用R或者JS的方案对吧?刚好我有现成的实现,用你给的测试数据就能跑起来:
import numpy as np from scipy.cluster.hierarchy import linkage, dendrogram import plotly.subplots as sp import plotly.graph_objects as go # 生成测试数据(固定随机种子方便复现) np.random.seed(42) X = np.random.randint(0, 10, size=(120, 10)) # 对行(Y轴样本)执行层次聚类 # 用ward方法最小化聚类内方差,适合大规模数据的聚类稳定性 row_linkage = linkage(X, method='ward') # 获取树状图的坐标数据,不生成默认的matplotlib图 row_dendro = dendrogram(row_linkage, no_plot=True) # 提取聚类后的行索引顺序,用来重排热图数据 row_order = row_dendro['leaves'] X_clustered = X[row_order, :] # 创建子图:1行2列,树状图占比15%宽度,热图占85% fig = sp.make_subplots( rows=1, cols=2, column_widths=[0.15, 0.85], horizontal_spacing=0.01, # 缩小间距让两个图视觉上无缝衔接 shared_yaxes=True # 共享Y轴保证树状图和热图完全对齐 ) # 绘制左侧树状图 # 从dendrogram结果中提取树的线条坐标 icoord = row_dendro['icoord'] dcoord = row_dendro['dcoord'] # 遍历每一段树线,添加到子图中 for xs, ys in zip(icoord, dcoord): fig.add_trace( go.Scatter( x=ys, y=[xs[0], xs[1], xs[2], xs[3]], mode='lines', line=dict(color='gray', width=1), showlegend=False ), row=1, col=1 ) # 调整树状图的轴样式:隐藏X轴,反转Y轴和热图对齐 fig.update_xaxes(visible=False, row=1, col=1) fig.update_yaxes(autorange='reversed', row=1, col=1) # 绘制右侧聚类后的热图 fig.add_trace( go.Heatmap( z=X_clustered, x=[f"Feature {i+1}" for i in range(X.shape[1])], y=[f"Sample {i+1}" for i in row_order], colorscale='Viridis' ), row=1, col=2 ) # 整体布局优化,适配120行数据的展示 fig.update_layout( title="仅左侧带树状图的聚类热图", height=800, # 调高画布高度,避免样本标签重叠 width=1000, margin=dict(l=50, r=50, t=50, b=50) ) # 展示图表 fig.show()
关键细节说明:
- 聚类处理:用
scipy的linkage做层次聚类,ward方法对大规模数据的聚类结果更稳定;dendrogram(no_plot=True)直接获取树状图的坐标数据,避免生成matplotlib的默认图。 - 子图对齐:设置
shared_yaxes=True和极小的horizontal_spacing,让树状图和热图的Y轴完全重合,视觉上像一个整体。 - 轴适配:反转树状图的Y轴,因为Plotly热图的Y轴默认是从下到上排列,和树状图的原始坐标方向相反,反转后才能完美对齐。
- 大规模数据适配:通过调整画布高度(
height=800)避免120行的样本标签重叠,同时树状图的线条用细灰色,不会占用过多视觉资源。
内容的提问来源于stack exchange,提问作者Petar
相关产品推荐
相关产品推荐

