python – 根据聚类按行划分seaborn矩阵

通过绘制2D矩阵并根据聚类对值进行排序,
This paper有一种很好的方法可视化具有二进制特征的数据集的聚类.

《python – 根据聚类按行划分seaborn矩阵》

在这种情况下,有三个簇,如黑色分界线所示;对行进行排序,并显示每个集群中的示例,列是每个示例的功能.

给定一个集群分配向量和一个pandas DataFrame,我如何使用Python库(例如seaborn)复制它?使用seaborn绘制DataFrame并不困难,也不会对DataFrame的行进行排序以与群集分配对齐.我最感兴趣的是如何显示描绘每个簇的黑色分界线.

虚拟数据:

"""
       col1  col2
x1_c0     0     1
x2_c0     0     1
================= I want a line drawn here
x3_c1     1     0
================= and here
x4_c2     1     0
"""
import pandas as pd
import seaborn as sns

df = pd.DataFrame(
    data={'col1': [0, 0, 1, 1], 'col2': [1, 1, 0, 0]},
    index=['x1_c0', 'x2_c0', 'x3_c1', 'x4_c2']
)
clus = [0, 0, 1, 2]  # This is the cluster assignment

sns.heatmap(df)

《python – 根据聚类按行划分seaborn矩阵》

最佳答案 mwaskom在评论中发布的链接是一个很好的起点.诀窍是弄清楚垂直和水平线的坐标是什么.

为了说明代码实际执行的操作,单独绘制所有行是值得的

%matplotlib inline

import pandas as pd
import seaborn as sns

df = pd.DataFrame(data={'col1': [0, 0, 1, 1], 'col2': [1, 1, 0, 0]},
                  index=['x1_c0', 'x2_c0', 'x3_c1', 'x4_c2'])

f, ax = plt.subplots(figsize=(8, 6))

sns.heatmap(df)

ax.axvline(1, 0, 2, linewidth=3, c='w')
ax.axhline(1, 0, 1, linewidth=3, c='w')
ax.axhline(2, 0, 1, linewidth=3, c='w')
ax.axhline(3, 0, 1, linewidth=3, c='w')

f.tight_layout()

《python – 根据聚类按行划分seaborn矩阵》

axvline方法的工作方式是第一个参数是行的x位置,然后是行的下限和上限(在本例中为1,0,2).水平线取y位置,然后是线的x start和x stop.默认值将为整个绘图创建一条线,因此您通常可以将其保留.

上面的代码为数据框中的每个值创建一行.如果要为热图创建组,则需要在数据框中创建索引,或者要循环使用其他一些值列表.例如,使用来自this example的代码的更复杂的示例:

df = pd.DataFrame(data={'col1': [0, 0, 1, 1, 1.5], 'col2': [1, 1, 0, 0, 2]},
                  index=['x1_c0', 'x2_c0', 'x3_c1', 'x4_c2', 'x5_c2'])

df['id_'] = df.index
df['group'] = [1, 2, 2, 3, 3]
df.set_index(['group', 'id_'], inplace=True)
df

             col1  col2
group id_
1     x1_c0   0.0     1
2     x2_c0   0.0     1
      x3_c1   1.0     0
3     x4_c2   1.0     0
      x5_c2   1.5     2

然后使用组绘制热图:

f, ax = plt.subplots(figsize=(8, 6))

sns.heatmap(df)

groups = df.index.get_level_values(0)

for i, group in enumerate(groups):
    if i and group != groups[i - 1]:
        ax.axhline(len(groups) - i, c="w", linewidth=3)

ax.axvline(1, c="w", linewidth=3)

f.tight_layout()

《python – 根据聚类按行划分seaborn矩阵》

由于热图不是对称的,因此可能需要为列使用单独的for循环

点赞