matplotlib+pandas绘图时如何让x轴显示分组后的年月信息
问题原因
绘图仅显示年份的核心原因是:用pd.PeriodIndex(freq="M")生成的日期列是Pandas的月周期(Period)类型,Pandas调用Matplotlib绘图时对这类周期数据的默认刻度规则,会在时间跨度超过1年时自动折叠仅显示年份标签,不会细化到月维度。另外你的代码里存在2处会触发运行报错的笔误:
- 第一行统计结果赋值给了
avg1,第二行重命名时调用的是未定义的avg变量 - 重命名后的列名是
Avg # of Task(Task为单数),绘图时传入的列名是Avg # of Tasks(多了末尾的s)
解决方案
方案1:标准时间轴实现(推荐)
把周期类型转为Matplotlib可识别的datetime类型,手动指定x轴刻度格式为年-月,这种方式生成的是连续标准时间轴,后续缩放、调整刻度间隔都很方便,不会出现标签错位问题。
完整实现代码:
import pandas as pd import matplotlib.pyplot as plt import matplotlib.dates as mdates # 修正笔误后的月均统计代码 avg = df.groupby(pd.PeriodIndex(df['Date'], freq="M"))['Task Count'].mean().to_frame().reset_index() avg = avg.rename(columns={"Task Count": "Avg # of Task"}) # 将月周期类型转为datetime时间类型 avg['Date'] = avg['Date'].dt.to_timestamp() # 创建画布绘图 fig, ax = plt.subplots(figsize=(15, 8)) avg.plot(x="Date", y="Avg # of Task", ax=ax) # 配置x轴:按月份显示刻度,格式为「年-月」 ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1)) # 每1个月显示一个刻度 ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m')) # 刻度文本格式 plt.xticks(rotation=45) # 旋转标签避免文字重叠 plt.tight_layout() # 自动调整布局防止标签被截断 plt.show()
方案2:快速字符串转换实现
如果你的数据时间跨度不大(不超过2年),可以直接把周期列转为年-月格式的字符串,不需要额外导入Matplotlib的日期模块,直接绘图即可。缺点是x轴为分类轴,不是连续时间轴,数据量大时标签容易拥挤。
代码示例:
# 月均统计代码同方案1 avg = df.groupby(pd.PeriodIndex(df['Date'], freq="M"))['Task Count'].mean().to_frame().reset_index() avg = avg.rename(columns={"Task Count": "Avg # of Task"}) # 直接将月周期转为字符串格式 avg['Date'] = avg['Date'].astype(str) # 绘图,rot参数设置标签旋转角度 avg.plot(x="Date", y="Avg # of Task", figsize=(15, 8), rot=45) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Emily A
相关产品推荐
相关产品推荐

