seaborn clustermap:subplots_adjust取消颜色栏重定位

时间:2017-11-17 12:39:55

标签: python matplotlib seaborn

我正在尝试使用seaborn在侧面使用颜色条制作热图。但是,在我的实际应用案例中,我有很长的列名称,我旋转。这需要使用plt.subplots_adjust,否则标签不适合图像:

plt.setp(g.ax_heatmap.get_xticklabels(), rotation=90)
plt.subplots_adjust(bottom=0.5)

使用以下最小示例,我发现最后一个命令正在取消颜色条重定位:

#!/usr/bin/env python3

import seaborn as sns
import matplotlib.pyplot as plt

iris = sns.load_dataset("iris")
species = iris.pop("species")
# Make long column names
iris.columns = ["________".join(label.split("_")) for label in iris.columns]


g = sns.clustermap(iris, col_cluster=False, yticklabels=False)
# Relocate colour bar on the side
g.cax.set_position([.15, .2, .03, .45])
plt.setp(g.ax_heatmap.get_xticklabels(), rotation=90)
plt.savefig("/tmp/unadjusted.png")

plt.cla()

g = sns.clustermap(iris, col_cluster=False, yticklabels=False)
g.cax.set_position([.15, .2, .03, .45])
plt.setp(g.ax_heatmap.get_xticklabels(), rotation=90)
# Adjust to have the column labels not cut out
plt.subplots_adjust(bottom=0.5)
plt.savefig("/tmp/adjusted.png")

这会产生以下图像:

没有plt.subplots_adjust

unadjusted

使用plt.subplots_adjust

adjusted

为什么会这样?

这是一个错误吗?

我可以做些什么才能将颜色条放在我想要的位置,并确保我的旋转颜色标签不会被剪切?

1 个答案:

答案 0 :(得分:2)

根据@ImportanceOfBeingErnest的建议,我尝试在移动颜色条之前进行调整。这导致了以下图像:

adjusted_before

由于我实际上不想要树形图,只是聚类,我可以通过使用树状图框来放置颜色条来获得更令人满意的结果:

#!/usr/bin/env python3

import seaborn as sns
import matplotlib.pyplot as plt

iris = sns.load_dataset("iris")
species = iris.pop("species")
# Make long column names
iris.columns = ["________".join(label.split("_")) for label in iris.columns]

g = sns.clustermap(iris, col_cluster=False, yticklabels=False)
plt.setp(g.ax_heatmap.get_xticklabels(), rotation=90)
# Adjust to have the column labels not cut out
plt.subplots_adjust(bottom=0.5)
g.cax.set_position([.15, .2, .03, .45])
plt.savefig("/tmp/adjusted_before.png")

plt.cla()

g = sns.clustermap(iris, col_cluster=False, yticklabels=False)
plt.setp(g.ax_heatmap.get_xticklabels(), rotation=90)
# Adjust to have the column labels not cut out
plt.subplots_adjust(bottom=0.5)
# Remove the dendrogram (https://stackoverflow.com/a/42418968/1878788)
g.ax_row_dendrogram.set_visible(False)
# Use the dendrogram box to reposition the colour bar
dendro_box = g.ax_row_dendrogram.get_position()
dendro_box.x0 = (dendro_box.x0 + 2 * dendro_box.x1) / 3
g.cax.set_position(dendro_box)
# Move the ticks to the left (https://stackoverflow.com/a/36939552/1878788)
g.cax.yaxis.set_ticks_position("left")
# If we add a label to the colour bar
# (cbar_kws={"label" : "the_label"} in clustermap arguments)
# we also need to move the label
# g.cax.yaxis.set_label_position("left")
plt.savefig("/tmp/adjusted_before_using_row_dendrogram_box.png")

这会生成以下图像:

adjusted_before_using_row_dendrogram_box

编辑:plt.tight_layout也出现同样的问题。

进一步开发我的热图,我想添加带有图例的行颜色(使用this answer中提出的方法)。在我的实际应用案例中,图例需要从图像中剪切出足够的水平空间。

我想使用plt.tight_layout调整图片。这再次干扰了色条重新定位(并且甚至无法解决剪切图例问题......),如以下示例所示。

#!/usr/bin/env python3

import seaborn as sns
import matplotlib.pyplot as plt

iris = sns.load_dataset("iris")
species = iris.pop("species")
# Make long column names
iris.columns = ["________".join(label.split("_")) for label in iris.columns]


# Associating colours with species
species_list = species.unique()
label_colours = dict(zip(species_list, sns.color_palette("colorblind", len(species_list))))
row_colours = species.map(label_colours)

g = sns.clustermap(iris, col_cluster=False, yticklabels=False, row_colors=row_colours, cbar_kws={"label" : "measure"})
# Adding row colour legend
# https://stackoverflow.com/a/27992943/1878788
for (label, colour) in label_colours.items():
    # Make long label
    g.ax_col_dendrogram.bar(0, 0, color=colour, label="Iris___________________{}".format(label))
g.ax_col_dendrogram.legend(loc="center", ncol=3)
# Rotating column labels
plt.setp(g.ax_heatmap.get_xticklabels(), rotation=90)
# Adjust to have the column labels not cut out
plt.subplots_adjust(bottom=0.5)
# Remove the dendrogram (https://stackoverflow.com/a/42418968/1878788)
g.ax_row_dendrogram.set_visible(False)
# Use the dendrogram box to reposition the colour bar
dendro_box = g.ax_row_dendrogram.get_position()
dendro_box.x0 = (dendro_box.x0 + 2 * dendro_box.x1) / 3
g.cax.set_position(dendro_box)
# Move the ticks and labels to the left (https://stackoverflow.com/a/36939552/1878788)
g.cax.yaxis.set_ticks_position("left")
g.cax.yaxis.set_label_position("left")
plt.savefig("/tmp/with_row_colour_lengend.png")

plt.cla()

g = sns.clustermap(iris, col_cluster=False, yticklabels=False, row_colors=row_colours, cbar_kws={"label" : "measure"})
# Adding row colour legend
# https://stackoverflow.com/a/27992943/1878788
for (label, colour) in label_colours.items():
    # Make long label
    g.ax_col_dendrogram.bar(0, 0, color=colour, label="Iris___________________{}".format(label))
g.ax_col_dendrogram.legend(loc="center", ncol=3)
# Rotating column labels
plt.setp(g.ax_heatmap.get_xticklabels(), rotation=90)
# Adjust to have the column labels not cut out
plt.subplots_adjust(bottom=0.5)
# Remove the dendrogram (https://stackoverflow.com/a/42418968/1878788)
g.ax_row_dendrogram.set_visible(False)
# Use the dendrogram box to reposition the colour bar
dendro_box = g.ax_row_dendrogram.get_position()
dendro_box.x0 = (dendro_box.x0 + 2 * dendro_box.x1) / 3
g.cax.set_position(dendro_box)
# Move the ticks and labels to the left (https://stackoverflow.com/a/36939552/1878788)
g.cax.yaxis.set_ticks_position("left")
g.cax.yaxis.set_label_position("left")
plt.tight_layout()
plt.savefig("/tmp/tight_after.png")

plt.cla()

g = sns.clustermap(iris, col_cluster=False, yticklabels=False, row_colors=row_colours, cbar_kws={"label" : "measure"})
# Adding row colour legend
# https://stackoverflow.com/a/27992943/1878788
for (label, colour) in label_colours.items():
    # Make long label
    g.ax_col_dendrogram.bar(0, 0, color=colour, label="Iris___________________{}".format(label))
g.ax_col_dendrogram.legend(loc="center", ncol=3)
plt.tight_layout()
# Rotating column labels
plt.setp(g.ax_heatmap.get_xticklabels(), rotation=90)
# Adjust to have the column labels not cut out
plt.subplots_adjust(bottom=0.5)
# Remove the dendrogram (https://stackoverflow.com/a/42418968/1878788)
g.ax_row_dendrogram.set_visible(False)
# Use the dendrogram box to reposition the colour bar
dendro_box = g.ax_row_dendrogram.get_position()
dendro_box.x0 = (dendro_box.x0 + 2 * dendro_box.x1) / 3
g.cax.set_position(dendro_box)
# Move the ticks and labels to the left (https://stackoverflow.com/a/36939552/1878788)
g.cax.yaxis.set_ticks_position("left")
g.cax.yaxis.set_label_position("left")
plt.savefig("/tmp/tight_before.png")

这导致以下数字:

没有plt.tight_layout,最右边的标签被切断(物种应该是" virginica"):

large_row_colour_legend

重新定位颜色栏后调用plt.tight_layout

tight_after

在重新定位颜色条之前调用plt.tight_layout

tight_before