自定义注释 Seaborn 热图
Posted
技术标签:
【中文标题】自定义注释 Seaborn 热图【英文标题】:Custom Annotation Seaborn Heatmap 【发布时间】:2016-01-14 11:23:10 【问题描述】:我在 Python 中使用 Seaborn 创建热图。我可以使用传入的值来注释单元格,但我想添加表示单元格含义的注释。例如,我不想只看到0.000000
,而是希望看到相应的标签,例如“Foo”或0.000000 (Foo)
。
热图函数的Seaborn documentation 有点神秘,我认为参数是这里的关键:
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
参数时的(工作)输出:
当我做时的堆栈跟踪包括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
希望一切都有意义,如果任何人都可以提供任何帮助,我将不胜感激。
【问题讨论】:
你有没有设法解决这个问题? 【参考方案1】:此功能刚刚添加到最新版本的 Seaborn 0.7.1 中。
来自Seaborn update history:
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' 这仅对数字值有意义并且会导致文本标签出错。
【讨论】:
在某处是否有指向格式化选项的链接?好像没找到。 不是真的,但从我在code 中看到的,它是通过matplotlib 的ax
使用的: ax.text(x, y, (":" + self.fmt + " ").format(val), **text_kwargs) 如果值为整数,则可以使用 'd',但如果值为浮点数,则失败。
@SergioLucero 是否可以在此标签数组中添加浮点数?我收到一条错误消息 ValueError: Unknown format code 'g' for object of type 'numpy.str_'
为什么annot和data的形状要一致?【参考方案2】:
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]);
【讨论】:
谢谢@bushmanov。您知道更改注释的任何方法吗?还是失败了? @Tgsmith61591 感谢您的接受。热图是值的表示,所以我强烈相信热图本身没有办法允许从基础数据中提取不存在的标签Foo
。如果您确实需要附加标签,我会查看 matplotlib 如何在其绘图上覆盖文本。毕竟 seaborn 是 matplotlib。【参考方案3】:
我不相信这在当前版本中是可能的。如果您想采用 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)
请注意,您的文本标签的颜色可能存在问题。在这里,我创建了一个自定义 cmap
以使所有标签统一为黑色。
【讨论】:
这是一个不错的技巧!以上是关于自定义注释 Seaborn 热图的主要内容,如果未能解决你的问题,请参考以下文章