【问题标题】:How to create multiple seaborn heatmaps with a shared legend in one figure?如何在一个图中创建多个带有共享图例的 seaborn 热图?
【发布时间】:2019-06-06 13:11:12
【问题描述】:

我想在一个图中创建多个(此处:两个)seaborn 热图,其中热图具有不同的值范围,但应包含一个共享图例。

以下代码在一个图中创建了两个热图,但两个图的颜色编码不同。

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame(np.random.random((4,4)))
df2 = pd.DataFrame([1., .5, .9, .6])

fig, ax = plt.subplots(ncols=2, sharey=True)

sns_g = sns.heatmap(df, annot=True, yticklabels=True, ax=ax[0])
sns_g2 = sns.heatmap(df2, annot=True, cbar=False, ax=ax[1])

# fig.subplots_adjust(right=0.6)
# cbar_ax = fig.add_axes([1.1, 0.15, 0.05, .77])
# fig.colorbar(ax[1], cax=cbar_ax)

plt.tight_layout()

plt.show()

我在 sns_g 中包含 cbar=True 只是为了表明这两个图例代表不同的范围。我想明确地创建两个地块。

【问题讨论】:

  • @ImportanceOfBeingErnest:感谢您的参考。但是,我不确定在这种情况下如何添加颜色图。如果我取消注释代码中的行,我会得到:AttributeError: 'AxesSubplot' object has no attribute 'autoscale_None'

标签: python seaborn


【解决方案1】:

如果您想手动创建颜色条,您可以在网格中为其保留一个轴。使用vminvmax 指定限制,并使用热图之一(例如axs[0].collections[0])作为ScalarMappable 输入fig.colorbar

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame(np.random.random((4,4)))
df2 = pd.DataFrame([1., .5, .9, .6])

vmin = min(df.values.min(), df2.values.min())
vmax = max(df.values.max(), df2.values.max())

fig, axs = plt.subplots(ncols=3, gridspec_kw=dict(width_ratios=[4,1,0.2]))

sns.heatmap(df, annot=True, cbar=False, ax=axs[0], vmin=vmin)
sns.heatmap(df2, annot=True, yticklabels=False, cbar=False, ax=axs[1], vmax=vmax)

fig.colorbar(axs[1].collections[0], cax=axs[2])

plt.show()

【讨论】:

    【解决方案2】:

    fig.colorbar 想要一个 ScalarMappable 对象,而不是 Axes。但是 seaborn 的 API 让你不用担心。

    根据我在 seaborn.pydata.org 中搜索“heatmap”发现的docs,函数签名为:

    seaborn.heatmap(data, vmin=None, vmax=None, cmap=None, center=None,
                    robust=False, annot=None, fmt='.2g', annot_kws=None, 
                    linewidths=0, linecolor='white', cbar=True, cbar_kws=None, 
                    cbar_ax=None, square=False, xticklabels='auto',
                    yticklabels='auto', mask=None, ax=None, **kwargs)
    

    因此,您只需将相同的vminvmax 值传递给两个热图,但将cbar=Falsecbar=True 传递给另一个。

    【讨论】:

      猜你喜欢
      • 2021-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 2020-07-17
      • 2021-05-07
      • 2016-12-14
      相关资源
      最近更新 更多