Seaborn热图子图 - 保持轴比例一致

20

如果我有以下代码:

import seaborn 
import matplotlib.pyplot as plt
flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
f,(ax1,ax2,ax3) = plt.subplots(1,3,sharey=True)
g1 = sns.heatmap(flights,cmap="YlGnBu",cbar=False,ax=ax1)
g1.set_ylabel('')
g1.set_xlabel('')
g2 = sns.heatmap(flights,cmap="YlGnBu",cbar=False,ax=ax2)
g2.set_ylabel('')
g2.set_xlabel('')
g3 = sns.heatmap(flights,cmap="YlGnBu",ax=ax3)
g3.set_ylabel('')
g3.set_xlabel('')

如下图所示 - enter image description here

我该如何调整子图大小,使得g3轴与g1、g2轴相同宽度。由于我没有将色条添加到前两个轴中,seaborn会缩小第三个轴的大小以使整个图形保持一致。这是可以理解的。我想要这样的效果:

enter image description here

也许我需要制作一个四面板子图,其中第四面板仅包含色条?

1个回答

32

创建4个轴的方法是,在第四个轴中包含颜色条。您可以使用cbar_ax参数告诉热图在哪个轴上绘制颜色条。为了创建具有良好比例的轴,您可以使用subplots中的gridspec_kw参数。问题在于,这些轴将与颜色条共享y轴缩放,因此我们需要关闭sharey并手动共享前三个轴,使用ax1.get_shared_y_axes().join(ax2,ax3)。这反过来会创建不必要的轴标签,需要关闭。

import seaborn  as sns
import matplotlib.pyplot as plt
flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
f,(ax1,ax2,ax3, axcb) = plt.subplots(1,4, 
            gridspec_kw={'width_ratios':[1,1,1,0.08]})
ax1.get_shared_y_axes().join(ax2,ax3)
g1 = sns.heatmap(flights,cmap="YlGnBu",cbar=False,ax=ax1)
g1.set_ylabel('')
g1.set_xlabel('')
g2 = sns.heatmap(flights,cmap="YlGnBu",cbar=False,ax=ax2)
g2.set_ylabel('')
g2.set_xlabel('')
g2.set_yticks([])
g3 = sns.heatmap(flights,cmap="YlGnBu",ax=ax3, cbar_ax=axcb)
g3.set_ylabel('')
g3.set_xlabel('')
g3.set_yticks([])

# may be needed to rotate the ticklabels correctly:
for ax in [g1,g2,g3]:
    tl = ax.get_xticklabels()
    ax.set_xticklabels(tl, rotation=90)
    tly = ax.get_yticklabels()
    ax.set_yticklabels(tly, rotation=0)

plt.show()

在此输入图片描述


太好了!你能告诉我最后一件事吗?axcb的哪种方法可以用来设置标签?axcb.set_label()似乎没有任何作用。 - jwillis0720
1
我认为你的意思是 axcb.set_ylabel("一些标签") - ImportanceOfBeingErnest
@ImportanceOfBeingErnest FYI,这个方法不再建议使用,根据API更改日志3.6.0版。 "从get_shared_x_axes / get_shared_y_axes获取的分组器将是不可变的" ...现在我不确定如何在未来获得相同的结果。 - Bryce Schober
设置 subplots(... , sharey=True) 明显不能提供相同的结果,现在我不确定将来如何获得相同的结果,当共享的分组变成不可变时。 - Bryce Schober
我认为现在应该更新答案。对于这行代码ax1.get_shared_y_axes().join(ax2,ax3),我得到了AttributeError: 'GrouperView' object has no attribute 'join'的错误。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接