You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib中如何让二级标签位于一级标签下方并调整标记

解决Matplotlib/Seaborn热图的轴标记与标签层级问题

我来帮你搞定这个热图的标记和标签问题,咱们先理清核心需求,再一步步调整代码:

  • 在X、Y轴对应数值125、128、130、133、138、142、143的位置,添加大小为16的*标记
  • 让这些*二级标签位于一级数值标签的下方
  • 修复网格偏移的问题

原代码的问题主要是:标记位置未对应实际数值、标记大小未设置、双轴标签位置错误,以及网格和热图单元格未对齐。下面是修改后的完整代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.ticker as tkr
import matplotlib.patches as patches

# 读取数据
with open("1.txt") as f:
    lstx = [int(x) for x in f.read().split()]
with open("2.txt") as f:
    lsty = [int(x) for x in f.read().split()]
with open("3.txt") as f:
    lstz = [float(x) for x in f.read().split()]

# 轴标签格式化函数:把0-based刻度转为120+的数值
def numfmt(x, pos):
    return f'{int(x + 120)}'

# 转换为数组并构建DataFrame
x = np.array(lstx)
y = np.array(lsty)
z = np.array(lstz)
df = pd.DataFrame(np.array([y, x, z]).T, columns=['X_value','Y_value','Z_value'])
df['Z_value'] = pd.to_numeric(df['Z_value'])

# 创建热图
fig, ax = plt.subplots(figsize=(11,9))
pivotted = df.pivot('X_value','Y_value','Z_value')
ax = sns.heatmap(pivotted, cmap='plasma_r', vmin=0.0, vmax=234.525, cbar=True)

# 调整颜色条刻度大小
cbar = ax.collections[0].colorbar
cbar.ax.tick_params(labelsize=20)

# 反转Y轴(符合热图常见展示逻辑)
ax.invert_yaxis()

# 设置X/Y轴主刻度格式和大小
xfmt = tkr.FuncFormatter(numfmt)
ax.xaxis.set_major_formatter(xfmt)
ax.yaxis.set_major_formatter(xfmt)  # Y轴格式和X轴一致,直接复用函数

ax.set_xlabel('\nNumber', fontsize=24)
ax.set_ylabel('Number\n', fontsize=24)
ax.tick_params(axis='both', labelsize=16, pad=15)  # 给主标签留空间放二级标记

# ---------------------- 核心修改:添加二级*标记 ----------------------
# 需要标记的目标数值
target_values = [125, 128, 130, 133, 138, 142, 143]
# 转换为0-based的轴位置(主刻度0对应120,所以数值减120就是位置)
target_positions = [val - 120 for val in target_values]

# 在X轴添加*标记(位于主标签下方)
for pos in target_positions:
    ax.annotate('*', xy=(pos, 0), xycoords='data',
                xytext=(0, -18), textcoords='offset points',
                fontsize=16, ha='center', va='top')

# 在Y轴添加*标记(位于主标签左侧)
for pos in target_positions:
    ax.annotate('*', xy=(0, pos), xycoords='data',
                xytext=(-18, 0), textcoords='offset points',
                fontsize=16, ha='right', va='center')

# ---------------------- 修复网格偏移问题 ----------------------
# 让网格与热图单元格边界对齐
ax.set_xticks(np.arange(pivotted.shape[1]+1) - 0.5, minor=True)
ax.set_yticks(np.arange(pivotted.shape[0]+1) - 0.5, minor=True)
ax.grid(which='minor', color='gray', linestyle='-', linewidth=0.5, alpha=0.5)
ax.grid(which='major', visible=False)  # 关闭主网格,避免和次要网格冲突

# 添加矩形框(保留原需求)
rect3 = patches.Rectangle((5-0.5,5-0.5),13,13, linewidth=1.7, linestyle='--', edgecolor='black', facecolor='none')
ax.add_patch(rect3)

plt.tight_layout()
plt.show()

关键修改点说明:

  1. 精准定位标记:

    • 把目标数值转换成热图的0-based轴位置(val - 120),确保标记对应正确的单元格
    • 用ax.annotate()代替双轴方案,避免刻度冲突,更灵活控制标记位置
  2. 调整标记样式与位置:

    • 通过xytext设置偏移量,让*刚好落在主标签下方(X轴)或左侧(Y轴)
    • 直接设置fontsize=16,确保标记大小符合要求
  3. 修复网格对齐:

    • 把次要刻度设置为热图单元格的边界(np.arange(shape+1)-0.5),让网格完美贴合单元格
    • 关闭主网格,避免和次要网格重叠冲突
  4. 优化标签间距:

    • 主刻度设置pad=15,给二级标记留出足够显示空间,避免标签重叠

这样调整后,你的热图就能完全满足所有需求:标记位置准确、大小合适,二级标签在主标签下方,网格也能完美对齐热图单元格。

内容的提问来源于stack exchange,提问作者Hdez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:47:30