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

Matplotlib热力图Y轴刻度按月度日期增量标注问题

问题解决:Matplotlib热力图Y轴日期显示异常及标签拥挤问题

问题1:Y轴日期显示为1970年代的原因及修复

你错误地将日期转换后的数值(m_dates)直接作为Y轴刻度标签传入,导致Matplotlib把这些数值当成普通浮点数解析,而非日期序数。正确的做法是让Y轴坐标直接映射为日期数值,再通过日期定位器和格式化器处理显示逻辑。

问题2:大量日期导致Y轴标签拥挤的解决方案

使用Matplotlib的MonthLocator自动按月度生成刻度,搭配DateFormatter格式化日期;同时通过imshow的extent参数将Y轴坐标与日期值绑定,避免手动设置所有刻度。


修正后的完整代码

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.transforms import ScaledTranslation
import numpy as np
from datetime import datetime, timedelta
import random

matrix = [[5, 9, 0, 4],
          [0, 8, 3, 6],
          [9, 1, 0, 4],
          [0, 0, 3, 1]]

# 模拟真实数据集:生成30个跨多个月份的日期
dates = [datetime.today() - timedelta(days=x*10) for x in range(30)]
x_labels = ['Y29K', 'D950N', 'D142G', 'T95I']

title = 'Example Heatmap'
cbtitle = 'Mutation Count'

# 调整画布大小,适配长Y轴的日期显示
fig, ax = plt.subplots(figsize=(8, 10))

# 将日期转换为Matplotlib可识别的数值格式
y_dates_num = mdates.date2num(dates)
# 设置imshow的extent参数,让Y轴直接对应日期数值(注意imshow默认Y轴从上到下,需反转日期顺序)
im = ax.imshow(matrix, extent=[-0.5, len(x_labels)-0.5, y_dates_num[-1], y_dates_num[0]])

# 配置颜色条
max_val = round(int(np.max(matrix))/10)*10
color_bar_rnge = np.linspace(0, max_val, 10, endpoint=False)
cb = fig.colorbar(im, ticks=color_bar_rnge)
cb.ax.set_title(cbtitle)

# X轴标签设置
ax.set_xticks(np.arange(len(x_labels)), labels=x_labels)
plt.setp(ax.get_xticklabels(), rotation=90, ha="right", rotation_mode="anchor")

# 调整X轴标签偏移,避免与热力图重叠
dx, dy = -6, 0
offset = ScaledTranslation(dx / fig.dpi, dy / fig.dpi, fig.dpi_scale_trans)
for label in ax.xaxis.get_majorticklabels():
    label.set_transform(label.get_transform() + offset)

# Y轴月度刻度配置
ax.yaxis.set_major_locator(mdates.MonthLocator())  # 自动生成月度刻度位置
ax.yaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))  # 格式化日期为年-月格式

# 可选:添加次要刻度(如每周),用于更精细的参考
# ax.yaxis.set_minor_locator(mdates.WeekdayLocator())

ax.set_title(title)
fig.tight_layout()
plt.show()

关键修改说明

  1. extent参数绑定日期坐标:让Y轴直接对应日期的数值表示,Matplotlib可自动识别为日期轴,从根源解决1970日期错误。
  2. MonthLocator自动生成刻度:无需手动筛选日期,Matplotlib会根据数据范围自动选择月度刻度,避免标签拥挤。
  3. 画布大小调整:通过figsize适配大量日期的Y轴显示,提升可读性。

替代方案(不修改imshow坐标)

如果需要保持Y轴为行索引,可手动筛选月度刻度的位置:

# 保持Y轴为行索引,手动筛选每个月第一个出现的日期对应的刻度
ax.set_yticks(np.arange(len(dates)))
month_ticks = []
month_labels = []
seen_months = set()
for idx, date in enumerate(dates):
    month_key = (date.year, date.month)
    if month_key not in seen_months:
        seen_months.add(month_key)
        month_ticks.append(idx)
        month_labels.append(date.strftime('%Y-%m'))
ax.set_yticks(month_ticks, labels=month_labels)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 18:45:48