Python 自定义注释 Seaborn 热图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33158075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 12:53:35  来源:igfitidea点击:

Custom Annotation Seaborn Heatmap

pythonheatmapseaborn

提问by Tgsmith61591

I'm using Seaborn in Python to create a Heatmap. I'm able to annotate the cells with the values passed in, but I'd like to add annotations that signify what the cell means. For example, instead of merely seeing 0.000000, I'd like to see the corresponding label, for instance "Foo," or 0.000000 (Foo).

我在 Python 中使用 Seaborn 来创建热图。我可以用传入的值注释单元格,但我想添加表示单元格含义的注释。例如,0.000000我希望看到相应的标签,而不是仅仅看到,例如“Foo”或0.000000 (Foo)

The Seaborn documentationfor the heatmap function is a bit cryptic with the parameter that I believe is the key here:

热图函数的Seaborn 文档有点神秘,我认为参数是这里的关键:

annot_kws : dict of key, value mappings, optional
  Keyword arguments for ax.text when annot is True.

I tried setting annot_kwsto a dictionary of the aliases to the values, i.e., {'Foo' : -0.231049060187, 'Bar' : 0.000000}, etc., but I'm getting an AttributeError.

我尝试设置annot_kws为值的别名字典,即{'Foo' : -0.231049060187, 'Bar' : 0.000000},等,但我收到一个 AttributeError。

Here is my code (I've manually created the data array here for reproducability):

这是我的代码(为了可重复性,我在这里手动创建了数据数组):

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)

Here is the (working) output when I don't use the annot_kwsparameter:

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

Working output

工作输出

And here the stack trace for when I doinclude the annot_kwsparam:

在这里,当我在堆栈跟踪包括annot_kwsPARAM:

---------------------------------------------------------------------------
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

Finally, kws, the attribute I'm passing in the line in the stack trace, is the dictionary and it would look basically like this:

最后,kws我在堆栈跟踪的行中传递的属性是字典,它基本上如下所示:

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

Hope everything makes sense, and I'd appreciate any help anyone can give.

希望一切都有意义,我很感激任何人可以提供的任何帮助。

采纳答案by ojy

This feature has just been added in the recent version of Seaborn 0.7.1.

此功能刚刚添加到最新版本的 Seaborn 0.7.1 中。

From Seaborn update history:

The annot parameter of heatmap() now accepts a rectangular dataset in addition to a boolean value. If a dataset is passed, its values will be used for the annotations, while the main dataset will be used for the heatmap cell colors

Seaborn 更新历史记录

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

Here is an example

这是一个例子

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 = '')

Note, fmt = '' is necessary if you are using non-numeric labels, since the default value is fmt='.2g' which makes sense only for numeric values and would lead to an error for text labels. enter image description here

请注意,如果您使用非数字标签,则 fmt = '' 是必需的,因为默认值是 fmt='.2g' 这仅对数字值有意义并且会导致文本标签错误。 在此处输入图片说明

回答by Sergey Bushmanov

aanot_kwsin Seaborn serves a different purpose, namely, it provides access to howannotations are displayed, rather than whatis displayed

aanot_kws在Seaborn用于不同的用途,即,它提供了访问如何被显示的注释,而不是什么显示

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

在此处输入图片说明

回答by Sergey Bushmanov

I don't believe this is possible in the current version. If you are up to a hack-y workaround, you could do the following ...

我不相信在当前版本中这是可能的。如果您采用 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)

Note that you may have a problem with the coloring of your text labels. Here, I created a custom cmapto have all labels uniformly black.

请注意,您的文本标签的颜色可能有问题。在这里,我创建了一个自定义cmap,使所有标签都统一为黑色。