可以使用两种不同的数据帧进行着色和文本注释。创建原始数据帧的副本,比较偶数列和奇数列将创建布尔值的数据帧。这些布尔值(内部值
0
对于
False
和
1
对于
True
)然后决定颜色。
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
data = {'Profession': ['Author', 'Librarian', 'Pilot'],
'Australia_F': [20, 10, 78],
'Australia_M': [80, 34, 12],
'Canada_F': [55, 89, 67],
'Canada_M': [34, 33, 90],
'Kenya_F': [60, 89, 12],
'Kenya_M': [23, 12, 55]}
df = pd.DataFrame(data).set_index('Profession')
df_coloring = df.copy()
for colF, colM in zip(df_coloring.columns[::2], df_coloring.columns[1::2]):
df_coloring[colF] = df[colF] > df[colM]
df_coloring[colM] = df[colM] > df[colF]
sns.set_style('white')
plt.figure(figsize=(10, 8))
sns.heatmap(df_coloring, cmap='coolwarm', annot=df, fmt=".1f", linewidths=.5, cbar=False)
plt.xlabel('Country and Gender')
plt.ylabel('Profession')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
或者,你可以添加额外的分离,将性别放在顶部,将国家放在底部:
sns.set_style('white')
plt.figure(figsize=(10, 8))
ax = sns.heatmap(df_coloring, cmap='coolwarm', annot=df, fmt=".0f", linewidths=.5, cbar=False, annot_kws={"size": 22})
countries = [l.get_text()[:-2] for l in ax.get_xticklabels()[::2]]
ax_top = ax.secondary_xaxis('top')
ax_top.set_xticks(ax.get_xticks(), [l.get_text()[-1:] for l in ax.get_xticklabels()])
ax_top.tick_params(length=0)
ax.set_xticks(range(1, len(df.columns), 2), countries)
for i in range(0, len(df.columns) + 1, 2):
ax.axvline(i, lw=4, color='white')
for i in range(0, len(df) + 1):
ax.axhline(i, lw=4, color='white')
ax.set_xlabel('Country and Gender')
ax.set_ylabel('Profession')
plt.tight_layout()
plt.show()