自定义注释Seaborn热力图

32
我正在使用Python中的Seaborn创建热图。我可以使用传入的值注释单元格,但我想添加表示单元格含义的注释。例如,我想看到相应的标签,而不仅仅是看到0.000000,比如"Foo"或0.000000 (Foo)
Seaborn文档中,热图函数的参数有点晦涩,我认为这里的关键是:
annot_kws : dict of key, value mappings, optional
  Keyword arguments for ax.text when annot is True.

我尝试将annot_kws设置为一个字典,其中包含别名和值,例如{'Foo':-0.231049060187,'Bar':0.000000}等,但是我收到了一个AttributeError错误。
以下是我的代码(我在此手动创建数据数组以便重现):
data = np.array([[0.000000,0.000000],[-0.231049,0.000000],[-0.231049,0.000000]])
axs = sns.heatmap(data, vmin=-0.231049, vmax=0, annot=True, fmt='f', linewidths=0.25)

当我不使用annot_kws参数时,这是(工作)输出:

Working output

当我包括annot_kws参数时,这里是堆栈跟踪:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-57-38f91f1bb4b8> in <module>()
     12 
     13 
---> 14 axs = sns.heatmap(data, vmin=min(uv), vmax=max(uv), annot=True, annot_kws=kws, linewidths=0.25)
     15 concepts

/opt/anaconda/2.3.0/lib/python2.7/site-packages/seaborn/matrix.pyc in heatmap(data, vmin, vmax, cmap, center, robust, annot, fmt, annot_kws, linewidths, linecolor, cbar, cbar_kws, cbar_ax, square, ax, xticklabels, yticklabels, mask, **kwargs)
    272     if square:
    273         ax.set_aspect("equal")
--> 274     plotter.plot(ax, cbar_ax, kwargs)
    275     return ax
    276 

/opt/anaconda/2.3.0/lib/python2.7/site-packages/seaborn/matrix.pyc in plot(self, ax, cax, kws)
    170         # Annotate the cells with the formatted values
    171         if self.annot:
--> 172             self._annotate_heatmap(ax, mesh)
    173 
    174         # Possibly add a colorbar

/opt/anaconda/2.3.0/lib/python2.7/site-packages/seaborn/matrix.pyc in _annotate_heatmap(self, ax, mesh)
    138             val = ("{:" + self.fmt + "}").format(val)
    139             ax.text(x, y, val, color=text_color,
--> 140                     ha="center", va="center", **self.annot_kws)
    141 
    142     def plot(self, ax, cax, kws):

/opt/anaconda/2.3.0/lib/python2.7/site-packages/matplotlib/axes/_axes.pyc in text(self, x, y, s, fontdict, withdash, **kwargs)
    590         if fontdict is not None:
    591             t.update(fontdict)
--> 592         t.update(kwargs)
    593         self.texts.append(t)
    594         t._remove_method = lambda h: self.texts.remove(h)

/opt/anaconda/2.3.0/lib/python2.7/site-packages/matplotlib/artist.pyc in update(self, props)
    755             func = getattr(self, 'set_' + k, None)
    756             if func is None or not six.callable(func):
--> 757                 raise AttributeError('Unknown property %s' % k)
    758             func(v)
    759             changed = True

AttributeError: Unknown property tokenized

最后,我在堆栈跟踪中传递的kws属性是字典,大致如下:

kws = {'Foo': -0.231049060187, 'Bar': 0.0}

希望一切都说得通,我会感激任何人能给予的帮助。


你解决了这个问题吗? - Tom
4个回答

75

这个功能是在最近的Seaborn 0.7.1版本中添加的。

来自Seaborn更新历史

heatmap()函数的annot参数现在除了布尔值外,还接受矩形数据集。如果传递了数据集,则它的值将用于注释,而主要数据集将用于热力图单元格的颜色。

以下是一个例子:

data = np.array([[0.000000,0.000000],[-0.231049,0.000000],[-0.231049,0.000000]])
labels =  np.array([['A','B'],['C','D'],['E','F']])
fig, ax = plt.subplots()
ax = sns.heatmap(data, annot = labels, fmt = '')

请注意,如果您使用非数字标签,则需要将 fmt='',因为默认值为 fmt='.2g' 仅适用于数值,对于文本标签会导致错误。

enter image description here

有格式选项的链接在哪里?我似乎找不到它。 - Fabian Bosler
1
并不是,但从我在 code 中看到的,它是通过 matplotlib 的 ax 使用的:ax.text(x, y, ("{:" + self.fmt + "}").format(val), **text_kwargs)如果值是整数,可以使用 'd',但如果值是浮点数,则会失败。 - Sergio Lucero
3
@SergioLucero 这个标签数组中是否可以添加浮点数?我收到了一个错误消息 ValueError: Unknown format code 'g' for object of type 'numpy.str_'。 - Xavier Bourret Sicotte
为什么注释和数据的形状需要相同? - hansrajswapnil
fmt = '' 是救命之道 - undefined

9
我不认为在当前版本中这是可能的。如果你想要一个hack-y的解决方法,你可以按照以下步骤进行...
# Create the 1st heatmap without labels 
sns.heatmap(data=df1, annot=False,)

# create the second heatmap, which contains the labels,
# turn the annotation on,
# and make it transparent
sns.heatmap(data=df2, annot=True, alpha=0.0)

请注意,您可能会遇到文本标签颜色不一致的问题。在这里,我创建了一个自定义的来使所有标签都是统一的黑色。

这是一个不错的技巧! - hansrajswapnil

9

Seaborn中的aanot_kws提供了不同的功能,它提供了对注释显示方式的访问,而不是显示内容本身。

import matplotlib.pyplot as plt
import seaborn as sns

sns.set()
fig, ax = plt.subplots(1,2)
ata = np.array([[0.000000,0.000000],[-0.231049,0.000000],[-0.231049,0.000000]])
sns.heatmap(data, vmin=-0.231049, vmax=0, annot=True, fmt='f', annot_kws={"size": 15}, ax=ax[0])
sns.heatmap(data, vmin=-0.231049, vmax=0, annot=True, fmt='f', annot_kws={"size": 10}, ax=ax[1]);

enter image description here


谢谢@bushmanov。您知道更改注释的任何方法吗?还是说这是一个无望的事情? - TayTay
@Tgsmith61591 感谢您的接受。热力图是值的表示,因此我坚信热力图本身没有任何方法可以从底层数据中提取不存在的标签“Foo”。如果您确实需要附加标签,我建议查看 matplotlib 如何在其绘图上叠加文本。毕竟 seaborn 是基于 matplotlib 的。 - Sergey Bushmanov

1
这里有一个新的Python包,可以在Python中绘制复杂的热图:https://github.com/DingWB/PyComplexHeatmap。使用此包,您可以添加不同类型的注释(包括箱线图、散点图、条形图)。

PyComplexHeatmap exampel1 example2

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