Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding seaborn clustermap to figure with other plots

I am trying to put the following two plots onto the same figure:

import seaborn as sns; sns.set(color_codes=True)
import matplotlib.pyplot as plt
f, (ax1, ax2) = plt.subplots(1, 2, sharey=True)
iris = sns.load_dataset("iris")
sns.boxplot(data=iris, orient="h", palette="Set2", ax = ax1)
species = iris.pop("species")
lut = dict(zip(species.unique(), "rbg"))
row_colors = species.map(lut)
sns.clustermap(iris, row_colors=row_colors, ax = ax2)

I understand that clustermap returns a figure, so this doesn't work. However, I still need a way to present these plots next to each other (horizontal). sns.heatmap returns an axes, but it does not support clustering or color annotation .

What is the best way to do this ?

like image 466
Jack Arnestad Avatar asked Aug 12 '18 19:08

Jack Arnestad


1 Answers

Indeed, clustermap, as some other seaborn functions, creates its own figure. There is nothing you can do about that but as long as all other content you want to have in the final figure can be created inside axes, like in this case the boxplot, the solution is relatively easy.

You can simply work with the figure that clustermap has created for you. The idea would then be to manipulate the gridspec of the axes such that there is some place left for the other axes.

import seaborn as sns; sns.set(color_codes=True)
import matplotlib.pyplot as plt
import matplotlib.gridspec

iris = sns.load_dataset("iris")
species = iris.pop("species")

lut = dict(zip(species.unique(), "rbg"))
row_colors = species.map(lut)

#First create the clustermap figure
g = sns.clustermap(iris, row_colors=row_colors, figsize=(13,8))
# set the gridspec to only cover half of the figure
g.gs.update(left=0.05, right=0.45)

#create new gridspec for the right part
gs2 = matplotlib.gridspec.GridSpec(1,1, left=0.6)
# create axes within this new gridspec
ax2 = g.fig.add_subplot(gs2[0])
# plot boxplot in the new axes
sns.boxplot(data=iris, orient="h", palette="Set2", ax = ax2)
plt.show()

enter image description here

For the case when having multiple figure-level functions to combine the solution is much more complicated, as seen e.g. in this question.

like image 138
ImportanceOfBeingErnest Avatar answered Oct 14 '22 01:10

ImportanceOfBeingErnest