为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

墨色风雨 2022-08-25 14:37:03
我正在绘制一个海生的热图,并希望仅使用自定义文本注释特定单元格。import 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)fig, ax = plt.subplots()sns.heatmap(data, annot=labels, ax=ax, vmin=0, vmax=100)plt.show()上面的代码生成以下热图:注释行将生成以下热图:我想在单元格上仅显示非nan(或非零)文本。如何做到这一点?
查看完整描述

3 回答

?
GCT1015

TA贡献1827条经验 获得超4个赞

使用字符串数组而不是掩码数组:annot


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)


# 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()

查看完整回答
反对 回复 2022-08-25
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

要通过@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)


查看完整回答
反对 回复 2022-08-25
?
芜湖不芜

TA贡献1796条经验 获得超7个赞

只是要添加这个,因为我花了一些时间来弄清楚如何以编程方式为稍微不同的应用程序做类似的事情:我想从注释中抑制0值,但是由于这些值是交叉表操作的结果而产生的,因此我无法使用William Miller的好方法,除非将交叉表写出来,然后读回它似乎...不雅。


可能有一种更优雅的方法来做到这一点,但对我来说,运行它的速度快得离谱,而且非常简单。numpy


import numpy as np

import pandas as pd

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


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 function

an = np.vectorize(lambda x: '' if x<50 else str(round(x,-1)))(data.to_numpy())


sns.heatmap(

    data=data.to_numpy(), # Note this is now numpy too

    cmap='BuPu',

    annot=an,   # The matching ndarray of annotations

    fmt = '',   # Formats annotations as strings (i.e. no formatting)

    cbar=False, # Seems overkill if you've got annotations

    vmin=0, 

    vmax=data.max().max()

)

在标记轴方面,这可能会使生活变得更加困难,尽管它非常简单:.如果你在第一列中有轴标签,那么你需要在调用中使用(),但与自定义色彩映射表(例如0==white)相结合,你可以创建更容易查看的热图。ax.set_xticklabels(df.columns.values)ilocdata.iloc[:,1:]to_numpy


显然,粗略的舍入令人困惑(为什么80有不同的色调?),但你明白了:


查看完整回答
反对 回复 2022-08-25
  • 3 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信