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

如何将时间序列图的年日轴转换为月份缩写轴(Jan/Feb)

解决时间序列逐年对比的月份缩写坐标轴问题

我完全懂你的需求——要保留每日粒度的数据做逐年对比,但x轴想显示Jan、Feb这类月份缩写,而不是冰冷的年日数或者聚合后的月度数据。你的原代码其实已经搞定了每日数据的逐年对比,只是坐标轴的显示逻辑不对,咱们只需要给x轴做个自定义刻度调整就行,根本不用动数据的粒度。

解决方案核心思路

  1. 保留你原有的每日数据透视表(确保每一行都是全年对应第N天的数据)
  2. 生成每个月份起始位置对应的年日数(比如1月1日是第1天,2月1日是第32天,闰年也能覆盖)
  3. 把这些位置设为x轴刻度,替换成月份缩写作为标签

修改后的完整可运行代码

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

# 创建模拟时间序列数据
index = pd.date_range(start='01-Jan-2012', end='31-12-2018', freq='D')
data = np.random.randn(len(index))
df = pd.DataFrame(data, index, columns=['Data'])

# 按年日数透视,保留每日粒度数据
df_pivot = pd.pivot_table(df, index=df.index.dayofyear, columns=df.index.year, values='Data')

# 用闰年(2012年)做参考,生成每个月第一天的年日数和月份缩写
reference_year = pd.date_range(start='2012-01-01', end='2012-12-31', freq='D')
month_start_days = reference_year[reference_year.is_month_start]
tick_positions = month_start_days.dayofyear
tick_labels = [day.strftime('%b') for day in month_start_days]

# 绘图并设置自定义坐标轴
ax = df_pivot.plot()
ax.set_xticks(tick_positions)
ax.set_xticklabels(tick_labels)
ax.set_xlabel('Month')

plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.tight_layout()  # 自动调整布局,避免图例和标签被截断
plt.show()

关键细节解释

  • 保留每日数据:df_pivot的索引依然是dayofyear,每一行严格对应全年第N天的数据,完全没丢失每日粒度的信息。
  • 闰年参考的必要性:选2012年(闰年)做参考,是为了覆盖366天的极端情况,确保哪怕是闰年的2月29日也能正确对应到月份。
  • 自定义刻度逻辑:提取每个月第一天的年日数作为刻度位置,用strftime('%b')生成标准的月份缩写,这样x轴既符合月份的时间逻辑,又显示得直观友好。
  • 布局优化:plt.tight_layout()能自动调整图表元素的位置,避免右侧的图例或者x轴标签被画布截断。

额外说明

如果你的数据里包含非闰年,某些年份没有第366天,df_pivot里会出现NaN值,但matplotlib会自动跳过这些空值,不影响绘图效果,咱们的刻度设置依然完全有效。

这样就完美解决了你遇到的两个问题——既保留了每日数据,又让x轴显示清晰的月份缩写~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:54:35