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

使用Matplotlib、Pandas绘制不同频率时间数据:标记位置偏移问题

解决Pandas季度时间序列与垂线段标记位置偏移的问题

嘿,我之前也踩过这个坑!当你用Pandas绘制Q-DEC频率的季度时间序列后,Matplotlib的x轴会自动适配季度刻度,这时候直接添加垂直线就容易被强制对齐到最近的季度末。核心原因是Pandas绘图时会把时间索引转换成对应频率的数值化时间戳,后续添加元素如果没明确处理日期类型,就会触发自动对齐逻辑。下面给你几个实用的解决办法:

方法一:手动转换标记日期为Matplotlib数值格式

直接把标记日期转换成Matplotlib能识别的日期数值,绕开自动对齐的问题:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import date2num

# 构造示例季度时间序列
dates = pd.date_range(start='2020-01-01', end='2023-12-31', freq='Q-DEC')
ts = pd.Series(range(len(dates)), index=dates)

# 自定义非季度末的标记日期
mark_dates = ['2021-05-15', '2022-09-20']
# 转换为Matplotlib可用的数值格式
mark_dates_num = [date2num(pd.to_datetime(date)) for date in mark_dates]

# 绘制时间序列
ts.plot(figsize=(10,6))

# 添加垂直线,精准定位
for date_num in mark_dates_num:
    plt.axvline(x=date_num, color='crimson', linestyle='--', alpha=0.7)

plt.title('季度时间序列+精准垂直线标记')
plt.show()

方法二:全程用Matplotlib原生接口绘图

放弃Pandas的plot封装,直接用Matplotlib处理,能完全掌控x轴的定位逻辑:

import pandas as pd
import matplotlib.pyplot as plt

# 构造示例数据
dates = pd.date_range(start='2020-01-01', end='2023-12-31', freq='Q-DEC')
ts = pd.Series(range(len(dates)), index=dates)

# 标记日期(非季度末)
mark_dates = pd.to_datetime(['2021-05-15', '2022-09-20'])

# 用Matplotlib原生方法绘制时间序列
plt.figure(figsize=(10,6))
plt.plot(ts.index, ts.values, marker='o', label='季度序列')

# 添加垂直线,直接传入datetime对象即可
for date in mark_dates:
    plt.axvline(x=date, color='forestgreen', linestyle=':', alpha=0.7, label='标记点' if date == mark_dates[0] else "")

# 手动设置x轴为季度刻度,保持原需求的显示效果
plt.xticks(dates, [d.strftime('%Y-Q%q') for d in dates], rotation=45)
plt.legend()
plt.title('Matplotlib原生绘制+精准垂直线')
plt.tight_layout()
plt.show()

方法三:适配Pandas绘图后的轴转换器

如果坚持要用Pandas的plot方法,可以获取当前轴的日期转换器,确保标记日期被正确解析:

import pandas as pd
import matplotlib.pyplot as plt

# 构造示例数据
dates = pd.date_range(start='2020-01-01', end='2023-12-31', freq='Q-DEC')
ts = pd.Series(range(len(dates)), index=dates)

mark_dates = pd.to_datetime(['2021-05-15', '2022-09-20'])

# 用Pandas绘制时间序列并获取轴对象
ax = ts.plot(figsize=(10,6))
# 获取x轴的日期转换器
x_converter = ax.xaxis.converter

# 转换标记日期并添加垂直线
for date in mark_dates:
    date_val = x_converter.convert(date, None, ax.xaxis)
    ax.axvline(x=date_val, color='royalblue', linestyle='-', alpha=0.7)

plt.title('Pandas绘图+适配轴转换器的垂直线')
plt.show()

这几种方法都能完美解决标记被舍入到季度末的问题,你可以根据自己的代码习惯选一个最顺手的~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:47:12