从seaborn clustermap结果重新排序高级集群

时间:2019-05-22 14:29:55

标签: python matplotlib seaborn hierarchical-clustering

是否可以通过脚本从下图的ab?我正在使用seaborn.clustermap()转到a(即,行的顺序被保留。但是,列的顺序仅在第二高的级别上改变)。

我想知道是否可以使用seaborn.matrix.ClusterGrid返回的seaborn.clustermap(),对其进行修改并绘制修改后的结果。  enter image description here   b P.S。。我要问的原因是订单具有含义(首先是蓝色,然后是绿色,最后是红色)。

更新: 这是一个生成情况的小数据集:

df = pd.DataFrame([[1, 1.1, 0.9, 1.9, 2, 2.1, 2.8, 3, 3.1], 
                   [1.8, 2, 2.1, 0.7, 1, 1.1, 2.7, 3, 3.3]],
              columns = ['d1', 'd2', 'd3', 
                         'l3', 'l2', 'l1', 
                         'b1', 'b2', 'b3'],
              index = ['p1', 'p2'])

cg = sns.clustermap(df); ## returns a ClusterGrid

输出是这样的:

enter image description here

我们可以将以b开头的列作为早餐,将l开头的午餐和将d开头的晚餐。现在,顺序为breakfast -> dinner -> lunch。我想去breakfast -> lunch -> dinner

1 个答案:

答案 0 :(得分:0)

这就是我解决问题的方式。它可以工作,但可能不如人们所希望的那么优雅!

import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import linkage, dendrogram

# set the desired order of groups eg: breakfast, lunch, dinner
groups = ['b', 'l', 'd'] 

# reorder indexes/indices besed on the desired order
new_order = []
for group in groups:
    indexes = cg.data2d.columns.str.startswith(group)
    indexes_locs = np.where(indexes)[0].tolist()
    new_order += indexes_locs
    
## reorder df based on the new order
ordered_df = cg.data2d.iloc[:, new_order]

## Run clustermap on the reordered dataframe by disabling 
## the clustering for both rows and columns
ocg = sns.clustermap(ordered_df, 
                     row_cluster=False, 
                     col_cluster=False,
                    );

## draw dendrogram x-axis
axx = ocg.ax_col_dendrogram.axes
axx.clear()

with plt.rc_context({'lines.linewidth': 0.5}):
    
    link = cg.dendrogram_col.linkage ## extract the linkage information

    ## manualy inspect the linkage and determine the new desired order
    link[[4, 2]] = link[[2, 4]]  ## swaping the two groups of higher hierarchy
    
    ## draw the the dendrogram on the x-axis
    dendrogram(link, 
           color_threshold=0, 
           ax=axx,
           truncate_mode='lastp',
           orientation='top',
           link_color_func=lambda x: 'k'
          );

axx.set_yticklabels(['']*len(axx.get_yticklabels()))
axx.tick_params(color='w')
    
## draw dendrogram y-axis (no chage here)
axy = ocg.ax_row_dendrogram.axes
axy.clear()

with plt.rc_context({'lines.linewidth': 0.5}):
    
    ## draw the the dendrogram on the y-axis
    dendrogram(cg.dendrogram_row.linkage, 
           color_threshold=0, 
           ax=axy,
           truncate_mode='lastp',
           orientation='left',
           link_color_func=lambda x: 'k',
          );

axy.set_xticklabels(['']*len(axy.get_yticklabels()))
axy.tick_params(color='w')
# axy.invert_yaxis() # we might need to invert y-axis

输出看起来像这样: enter image description here