You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib中正确连接两个层次聚类树状图?

解决Matplotlib层次聚类树状图标签连线错位问题

问题说明

使用Matplotlib绘制两个数据集(X1、X2)的层次聚类树状图并并排展示时,无法正确连接两个树状图的对应标签,连线出现错位或缺失。

错误原因

原代码中匹配右侧标签时,使用names.index(left_name)获取的是原始数据索引,而非该标签在右侧树状图叶子中的实际位置。右侧树状图的叶子顺序由dn2['leaves']决定,必须通过原始索引找到其在该列表中的位置,才能得到正确的y坐标。

修正后的代码

import matplotlib.pyplot as plt
import scipy.cluster.hierarchy as hierarchy
import numpy as np

# 样本数据
np.random.seed(20240406)
X1 = np.random.rand(10, 12)
X2 = np.random.rand(10, 12)
names = ['Jack', 'Oxana', 'John', 'Chelsea', 'Mark', 'Alice', 'Charlie', 'Rob', 'Lisa', 'Lily']

# 创建画布和子图,sharey=True确保y轴对齐
fig, axes = plt.subplots(1, 3, figsize=(12, 6), sharey=True)

# 绘制左侧树状图(X1)
Z1 = hierarchy.linkage(X1, method='complete')
dn1 = hierarchy.dendrogram(Z1, ax=axes[0], orientation='left', labels=names)
axes[0].set_title('Left Dendrogram for X1')
axes[0].set_xlabel('Distance')

# 绘制右侧树状图(X2)
Z2 = hierarchy.linkage(X2, method='complete')
dn2 = hierarchy.dendrogram(Z2, ax=axes[2], orientation='right', labels=names)
axes[2].set_title('Right Dendrogram for X2')
axes[2].set_xlabel('Distance')

# 获取左右树状图的叶子顺序(原始数据索引)
leaves_left = dn1['leaves']
leaves_right = dn2['leaves']

# 构建正确的连接关系:左侧叶子位置 ↔ 右侧叶子位置
connections = []
for left_pos, original_idx in enumerate(leaves_left):
    try:
        # 找到原始索引在右侧叶子中的位置
        right_pos = leaves_right.index(original_idx)
        connections.append((left_pos, right_pos))
    except ValueError:
        continue  # 标签不存在则跳过

# 绘制跨轴连接线
for left_y, right_y in connections:
    # 转换左右子图坐标到中间子图坐标系
    left_point = axes[0].transAxes.transform((1, left_y))
    right_point = axes[2].transAxes.transform((0, right_y))
    left_in_middle = axes[1].transData.inverted().transform(left_point)
    right_in_middle = axes[1].transData.inverted().transform(right_point)
    axes[1].plot([left_in_middle[0], right_in_middle[0]], [left_in_middle[1], right_in_middle[1]], 'k-', alpha=0.5)

# 配置中间子图
axes[1].set_title('Connections')
axes[1].axis('off')

plt.tight_layout()
plt.show()

关键修正点

  • sharey=True:创建子图时启用该参数,确保三个子图的y轴范围、刻度完全对齐,从根源避免轴范围不一致导致的错位。
  • 精准匹配叶子位置:通过leaves_right.index(original_idx)获取标签在右侧树状图中的实际y坐标,而非使用原始数据索引。
  • 跨轴坐标转换:利用Matplotlib的坐标转换工具,将左右子图的坐标映射到中间子图坐标系,保证跨轴连线的精准对齐。

内容的提问来源于stack exchange,提问作者Umar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 14:24:45