46

I have several questions about labeling for clustermap in seaborn. First is it possible to extract the the distance values for the hierarchical clustering, and plot the value on the tree structure visualization (maybe only the first three levels).

Here is my example code for creating a clustermap plot:

import pandas as pd
import numpy as np
import seaborn as sns
get_ipython().magic(u'matplotlib inline')

m = np.random.rand(50, 50)
df = pd.DataFrame(m, columns=range(4123, 4173), index=range(4123, 4173))
sns.clustermap(df, metric="correlation")

enter image description here

The other two questions are: - How to rotate the y labels since they overlaps together.
- How to move the color bar to the bottom or right. (There was a question for heatmap, but does not work for my case. Also does not address the color bar position)

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Bin
  • 3,645
  • 10
  • 33
  • 57
  • 1
    Are you using the latest versions of Seaborn, etc? I pasted your example code into a notebook on tmpnb.org, and the axis labels on the right are horizontal. – jb326 Jan 05 '16 at 02:23
  • @jb326, I just test this example code on tmpnb which works well. However, when I paste my example at the end of my very long program, the labels become vertical. In my program I did many customized plotting before this one, I guess some other plotting changed the default setting of matplotlib or seaborn. Thanks for helped me find this possible explanation.. – Bin Jan 05 '16 at 17:11

4 Answers4

59

I had the exact same issue with the labels on the y-axis being rotated and found a solution. The issue is that if you do plt.yticks(rotation=0) like suggested in the question you referenced, it will rotate the labels on your colobar due to the way ClusterGrid works.

To solve it and rotate the right labels, you need to reference the Axes from the underlying Heatmap and rotate these:

cg = sns.clustermap(df, metric="correlation")
plt.setp(cg.ax_heatmap.yaxis.get_majorticklabels(), rotation=0)

For your other question about the colorbar placement, I don't think this is supported at the moment, as indicated by this Github issue unfortunately.

And finally for the hierarchical clustering distance values, you can access the linkage matrics for rows or columns with:

cg = sns.clustermap(df, metric="correlation")
cg.dendrogram_col.linkage # linkage matrix for columns
cg.dendrogram_row.linkage # linkage matrix for rows
Charles Menguy
  • 40,830
  • 17
  • 95
  • 117
  • 3
    I used `plt.setp(cg.ax_heatmap.yaxis.get_majorticklabels(), rotation=0)` in a jupyter notebook and it did what it was supposed to but it also returned a vertical column of `None`s before plotting the plot? – KillerSnail Apr 28 '16 at 10:50
  • 1
    @KillerSnail I found that adding a `plt.show()` after the `plt.setp` got the list of `None`'s to disappear. – lurknobserve Dec 22 '16 at 16:29
  • How can I rotate the labels as above and give x and y axis labels, the labels are applied to the last active axis so goes to the legend. I tried a few things but couldn't find the correct way to do it. Here's the code to recreate (its a confusion matrix): cg = sns.clustermap(cm) plt.setp(cg.ax_heatmap.yaxis.get_majorticklabels(), rotation=0) plt.xlabel('Predicted Label') plt.ylabel('True Label') plt.show() – Edward Burgin Aug 04 '17 at 14:44
  • I tried the axis rotation Spyder, but nothing happened :( – Selah Apr 11 '18 at 21:20
9
import seaborn as sns   
g = sns.clustermap(heatmap_df, metric="correlation") 

plt.setp(g.ax_heatmap.get_yticklabels(), rotation=0)  # For y axis
plt.setp(g.ax_heatmap.get_xticklabels(), rotation=90) # For x axis
Surya
  • 11,002
  • 4
  • 57
  • 39
2

A bit different way to rotate labels

g.ax_heatmap.set_yticklabels(g.ax_heatmap.get_yticklabels(), rotation=0)
1

you can move the colorbar around by changing the position of it's axis cax: cg.cax.set_position((.85,.1,.1,.1)), for instance, where (a,b,c,d) are the x starting position, y starting position, x width and y height of the axis, respectively, in terms of axis coordinates.

tikacp
  • 43
  • 1
  • 6