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有不同的色調?),但你明白了:
添加回答
舉報