3 回答
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()
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)
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有不同的色调?),但你明白了:
添加回答
举报