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

Pandas按月年分组绘图时DatetimeIndex坐标轴格式化问题求助

问题:Pandas按年月分组绘图时X轴标签无法全部格式化的解决办法

使用Pandas绘制按年月分组的数据时,遇到X轴标签格式化异常:仅能修改最右侧的xtick标签,其余标签无法更改;修改格式时日期会重置;将DatetimeIndex转为字符串替换xticklabels也仅能更新最后一个标签。希望保留每3个月显示一个标签的设置,但每个标签都包含年份。

环境:Python 3.9.13、Pandas 1.4.4、Matplotlib 3.5.2

原测试代码:

from matplotlib import pyplot as plt
import pandas as pd
import numpy as np

# generate DataFrame
df = pd.DataFrame(data = {
    "value": np.random.rand(1000),
    "day": np.random.randint(1, 28+1, 1000),
    "month": np.random.randint(1, 12+1, 1000),
    "year": np.random.randint(2005, 2010+1, 1000)
})
df["date"] = pd.to_datetime(df[['year', 'month', 'day']])

# group the data by month (and also year)
monthly = df.groupby(pd.Grouper(key="date", freq="M")).sum()

# plot the data
ax = monthly["2008-02":"2009-03"].value.plot.line()

# optional different formatter I've tried
import matplotlib.dates as mdates
from matplotlib.dates import DateFormatter
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
date_form = DateFormatter("%m-%Y")
ax.xaxis.set_major_formatter(date_form)

解决方案

问题根源是Pandas绘图后,Matplotlib的X轴主定位器未明确指定,导致格式化器仅作用于部分标签。通过先设置主定位器为固定间隔的月度刻度,再配合格式化器即可解决,同时保留每3个月显示一个标签的需求。

修改后的代码:

from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
import matplotlib.dates as mdates
from matplotlib.dates import DateFormatter
from pandas.plotting import register_matplotlib_converters

register_matplotlib_converters()

# 生成DataFrame
df = pd.DataFrame(data = {
    "value": np.random.rand(1000),
    "day": np.random.randint(1, 28+1, 1000),
    "month": np.random.randint(1, 12+1, 1000),
    "year": np.random.randint(2005, 2010+1, 1000)
})
df["date"] = pd.to_datetime(df[['year', 'month', 'day']])

# 按年月分组求和
monthly = df.groupby(pd.Grouper(key="date", freq="M")).sum()

# 绘制指定时间段的数据
ax = monthly["2008-02":"2009-03"].value.plot.line()

# 关键1:明确设置X轴主定位器,每3个月生成一个刻度标签
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=3))
# 关键2:设置日期格式化器,强制每个标签显示年月
date_form = DateFormatter("%m-%Y")
ax.xaxis.set_major_formatter(date_form)

# 可选优化:旋转标签避免重叠,调整布局
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

核心说明

  • mdates.MonthLocator(interval=3):替代Pandas默认的自动刻度逻辑,明确指定每3个月生成一个主刻度,确保格式化器能作用于所有标签。
  • DateFormatter("%m-%Y"):强制每个标签同时显示月份和年份,满足需求。
  • 旋转标签和调整布局是可选的优化操作,避免标签重叠影响可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:25:23