如何基于双索引DataFrame绘制三角热力图
实现三角热力图的解决方案
你的问题出在透视后的DataFrame包含大量NaN值(上三角区域,也就是min > max的部分),普通热力图会默认忽略这些值,导致只显示有数据的对角线和下三角的一条“线”。我们可以通过**掩码(mask)**来只显示有数据的三角区域,同时美化热力图的显示效果。
以下是完整的实现步骤和代码:
步骤1:确认透视后的数据结构
首先看一下你透视后的df,它的行是min值,列是max值,只有当min <= max时才有对应的score,其余位置都是NaN:
print(df)
输出大概是:
max 1 2 3 4 5 min 1 0.537829 0.553661 0.573658 0.592656 0.607377 2 NaN 0.552494 0.575936 0.592823 0.609210 3 NaN NaN 0.587435 0.599433 0.613821 4 NaN NaN NaN 0.609321 0.618265 5 NaN NaN NaN NaN 0.627541
步骤2:创建掩码并绘制三角热力图
我们使用seaborn.heatmap的mask参数,把不需要显示的上三角区域(min > max)隐藏起来,同时添加必要的美化设置:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 读取并处理数据 data_str = """1 1 0.5378291300966559\n1 2 0.5536607043661815\n2 2 0.5524941673147428\n1 3 0.5736584823908455\n2 3 0.5759360071103211\n3 3 0.5874347294745028\n1 4 0.5926563715142762\n2 4 0.5928230196644817\n3 4 0.5994333962893011\n4 4 0.6093211865348295\n1 5 0.6073769581157649\n2 5 0.6092100877680258\n3 5 0.6138206865903788\n4 5 0.6182646372625263\n5 5 0.6275413842906343""" data = [{'min':line.split()[0], 'max':line.split()[1], 'score':line.split()[2]} for line in data_str.split('\n')] df = pd.DataFrame(data, dtype=float).pivot('min', 'max', 'score') # 创建掩码:隐藏min > max的区域 mask = df.index[:, None] > df.columns # 设置绘图风格 sns.set_style("white") # 绘制热力图 plt.figure(figsize=(8, 6)) ax = sns.heatmap(df, mask=mask, annot=True, fmt=".4f", cmap="YlGnBu", cbar=True, xticklabels=True, yticklabels=True) # 设置标题和坐标轴标签 ax.set_title("三角热力图(min <= max)") ax.set_xlabel("max") ax.set_ylabel("min") # 调整布局,防止标签被截断 plt.tight_layout() plt.show()
代码解释
- 掩码(mask):
df.index[:, None] > df.columns生成一个布尔矩阵,当行索引(min)大于列索引(max)时为True,这些区域会被热力图隐藏。 - annot=True:显示每个单元格的具体数值,
fmt=".4f"控制数值保留4位小数。 - cmap:设置热力图的颜色映射,你可以根据喜好换成其他配色(比如"viridis"、"coolwarm"等)。
- cbar=True:显示颜色条,方便查看数值对应的颜色。
运行这段代码后,你就能得到一个清晰的三角热力图,显示所有min <= max对应的score值啦!
内容的提问来源于stack exchange,提问作者alvas
相关产品推荐
相关产品推荐

