向热图中的特定单元格添加注释

我正在绘制一个海生的热图,并希望仅使用自定义文本注释特定单元格。


import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

import seaborn as sns

from io import StringIO


data = StringIO(u'''75,83,41,47,19

                    51,24,100,0,58

                    12,94,63,91,7

                    34,13,86,41,77''')


labels = StringIO(u'''7,8,4,,1

                    5,2,,2,8

                    1,,6,,7

                    3,1,,4,7''')


data = pd.read_csv(data, header=None)

data = data.apply(pd.to_numeric)


labels = pd.read_csv(labels, header=None)

#labels = np.ma.masked_invalid(labels)


fig, ax = plt.subplots()

sns.heatmap(data, annot=labels, ax=ax, vmin=0, vmax=100)

plt.show()

上面的代码生成以下热图:

http://img2.mukewang.com/630718a800015f2a04480331.jpg

注释行将生成以下热图:

我想在单元格上仅显示非nan(或非零)文本。如何做到这一点?


墨色风雨
浏览 122回答 3
3回答

GCT1015

使用字符串数组而不是掩码数组:annotimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsfrom io import StringIOdata = StringIO(u'''75,83,41,47,19                    51,24,100,0,58                    12,94,63,91,7                    34,13,86,41,77''')labels = StringIO(u'''7,8,4,,1                    5,2,,2,8                    1,,6,,7                    3,1,,4,7''')data = pd.read_csv(data, header=None)data = data.apply(pd.to_numeric)labels = pd.read_csv(labels, header=None)#labels = np.ma.masked_invalid(labels)# Convert everything to strings:annotations = labels.astype(str)annotations[np.isnan(labels)] = ""fig, ax = plt.subplots()sns.heatmap(data, annot=annotations, fmt="s", ax=ax, vmin=0, vmax=100)plt.show()

蓝山帝景

要通过@mrzo来补充答案,您可以使用 in 将 s 存储为空字符串,并用于转换为就地字符串:na_filter=Falseread_csv()nanpandas.DataFrame.astype()# ...labels = pd.read_csv(labels, header=None, na_filter=False).astype(str)sns.heatmap(data, annot=labels, fmt='s', ax=ax, vmin=0, vmax=100)

芜湖不芜

只是要添加这个,因为我花了一些时间来弄清楚如何以编程方式为稍微不同的应用程序做类似的事情:我想从注释中抑制0值,但是由于这些值是交叉表操作的结果而产生的,因此我无法使用William Miller的好方法,除非将交叉表写出来,然后读回它似乎...不雅。可能有一种更优雅的方法来做到这一点,但对我来说,运行它的速度快得离谱,而且非常简单。numpyimport numpy as npimport pandas as pdimport seaborn as snsfrom io import StringIOdata = StringIO(u'''75,83,41,47,19&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 51,24,100,0,58&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 12,94,63,91,7&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 34,13,86,41,77''')data = pd.read_csv(data, header=None)data = data.apply(pd.to_numeric)# For more complex functions you could write a def instead# of using this simple lambda functionan = np.vectorize(lambda x: '' if x<50 else str(round(x,-1)))(data.to_numpy())sns.heatmap(&nbsp; &nbsp; data=data.to_numpy(), # Note this is now numpy too&nbsp; &nbsp; cmap='BuPu',&nbsp; &nbsp; annot=an,&nbsp; &nbsp;# The matching ndarray of annotations&nbsp; &nbsp; fmt = '',&nbsp; &nbsp;# Formats annotations as strings (i.e. no formatting)&nbsp; &nbsp; cbar=False, # Seems overkill if you've got annotations&nbsp; &nbsp; vmin=0,&nbsp;&nbsp; &nbsp; vmax=data.max().max())在标记轴方面,这可能会使生活变得更加困难,尽管它非常简单:.如果你在第一列中有轴标签,那么你需要在调用中使用(),但与自定义色彩映射表(例如0==white)相结合,你可以创建更容易查看的热图。ax.set_xticklabels(df.columns.values)ilocdata.iloc[:,1:]to_numpy显然,粗略的舍入令人困惑(为什么80有不同的色调?),但你明白了:
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python