user40267
user40267

Reputation: 51

seaborn clustermap row reorder

I am trying to re-order a seaborn clustermap using the row order of a former clustermap, in this way:

p = sns.clustermap(m1, cmap='RdBu_r', linewidths=0.5)
order = p.dendrogram_row.reordered_ind
ind = m2.index[order]
m2 = m2.reindex(ind)
sns.clustermap(m2, cmap='RdBu_r', linewidths=0.5)

The m2 is sorted correctly when I print it but when I put it in the clustermap the heatmap is not sorted, could you help me?

Upvotes: 2

Views: 6101

Answers (1)

csk
csk

Reputation: 91

I think clustermap is plotted according to a clustering, regardless what order you pass in. It may be a solution to create a custom distance matrix and then pass it as a linkage. If you got your cluster labels from a previous clustering then just simply create a distance matrix, where the distance is zero if two items are in the same cluster.

import pandas as pd
import seaborn as sns
import numpy as np
from scipy.cluster.hierarchy import linkage
import scipy.spatial.distance as ssd

# create some random 3 dimensional data
data = pd.DataFrame(index=range(10), columns=["x", "y", "z"], 
data=np.random.random(size=(10,3)))

# create some random clustering with 3 different labels
cl_labels = [0,1,2]
cluster_labels = np.random.choice(cl_labels, size=data.shape[0])
prepared_clustering = pd.Series(index=data.index, data=cluster_labels)

# create a "distance" matrix
# distance for items in the same cluster will be zero, distance to elements outside the cluster are arbitrary (non-zero)
d = np.array([cluster_labels]*10)
distance_matrix = pd.DataFrame(index=data.index, columns=data.index, data = (d != d.T)).astype(int)

# create some colors to illustrate the clustering
colors = dict(zip(cl_labels, sns.hls_palette(len(cl_labels), l=0.5, s=0.8)))
row_colors = prepared_clustering.map(colors)

# plotting the clustermap
sns.clustermap(data,
           col_cluster=False,
           # don't turn off row_clustering, because it will do some default clustering/ordering
           row_cluster=True,
           # set the row_linkage to a custom linkage generated from the distance matrix
           # have no clue, but without the ssd.squareform a warning is displayed. the result is the same anyway
           #row_linkage=linkage(distance_matrix),
           row_linkage=linkage(ssd.squareform(distance_matrix)),
           # decorate with the rows
           row_colors=row_colors
          )

Clustermap with predefined clusters

Upvotes: 2

Related Questions