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

为什么matplotlib无法正确格式化月度时间序列的x轴日期

问题原因

pandas内置的plot方法会自动根据时间索引的频率选择坐标刻度的计数逻辑:

  • 高频的日度及以上粒度数据,默认使用和matplotlib日期模块兼容的日期序数(以公元0年为基准的天数计数),因此用mdates.DateFormatter解析可以正常显示
  • 低频的月度、季度、年度粒度数据,pandas默认会使用自身的周期计数逻辑(以1970年为基准的周期数计数,月度数据就是1970年至今的总月数),而mdates.DateFormatter会把这个周期数误当成matplotlib的日期天序数解析,最终就会显示为1970年附近的错误日期。

错误的月度数据显示效果如下:
月度数据错误绘图效果
正常的日度数据显示效果如下:
日度数据正常绘图效果

解决方案

调用df.plot时添加x_compat=True参数,强制pandas使用matplotlib兼容的日期序数作为x轴坐标单位,后续的日期格式化逻辑就可以正常生效。

修正后的代码如下:

import numpy as np
import pandas as pd
import matplotlib.dates as mdates 

# 提前定义rows变量,原代码缺失该变量定义
rows = 60
# 生成时间序列,切换freq参数即可切换日度/月度
years = pd.date_range(start='1/1/2018', periods=rows, freq='M')
# 生成模拟数据
np.random.seed(0)
data1 = np.random.randn(len(years))

ts1 = pd.Series(data=data1, index=years)
data = {'check': ts1}
df = pd.concat(data, axis=1)

# 新增x_compat=True参数
ax = df.plot(figsize=(20, 5), x_compat=True)

ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y %b"))

如果不想用x_compat参数,也可以改用pandas自带的刻度格式化工具,示例如下:

from matplotlib.ticker import FuncFormatter

def date_formatter(x, pos):
    # 把pandas返回的周期序数转成对应的日期
    date = df.index[int(x)]
    return date.strftime("%Y %b")

ax = df.plot(figsize=(20, 5))
ax.xaxis.set_major_formatter(FuncFormatter(date_formatter))

两种方案都可以正确显示月度数据的x轴日期,不会再出现1970年的错误基准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:36:07