通过绘制2D矩阵并根据聚类对值进行排序,
This paper有一种很好的方法可视化具有二进制特征的数据集的聚类.
在这种情况下,有三个簇,如黑色分界线所示;对行进行排序,并显示每个集群中的示例,列是每个示例的功能.
给定一个集群分配向量和一个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)
最佳答案 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()
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()
由于热图不是对称的,因此可能需要为列使用单独的for循环