Matplotlib设置日期X轴刻度:仅一月显示年份,修复1970/01异常
问题解决:堆叠柱状图X轴日期刻度优化(仅一月显示年份)
问题背景
用pandas的datetime类型日期列绘制堆叠柱状图时,希望优化X轴刻度显示逻辑:仅在一月对应的刻度上显示年份/月份,其余月份只显示月份。尝试了两种刻度格式化方式:
# 代码1 ax.xaxis.set_major_formatter('%Y/%m') ax.xaxis.set_minor_formatter('%m') # 代码2 ax.xaxis.set_major_formatter(DateFormatter('%Y/%m')) ax.xaxis.set_minor_formatter(DateFormatter('%m'))
但操作后X轴刻度全部变为1970/01,未达预期。原始绘图代码如下:
df_ref1 = data.groupby(['ref_date'])['fuel'].value_counts().unstack() fig, ax = plt.subplots(figsize=(6,4), dpi=200); df_ref1.plot(ax=ax, kind='bar', stacked=True) ax.set_title('Distribuição de tipo de combustível') ax.spines[['top','right', 'left']].set_visible(False) ax.set_xlabel('') plt.xticks(rotation = 45,ha='right'); ax.legend(['Gasolina','Disel', 'Álcool'],bbox_to_anchor=(.85, .95, 0, 0), shadow=False, frameon=False) plt.tight_layout()
原因分析
pandas绘制柱状图时,X轴本质是分类轴,刻度对应的是分组后datetime索引的位置序号(整数),而非datetime类型的时间戳。直接使用DateFormatter会把这些整数当成Unix时间戳解析,自然就显示成纪元起始的1970/01。
解决方法
手动生成自定义刻度标签,根据每个日期是否为一月来决定显示格式:
修改后完整代码
import matplotlib.pyplot as plt # 假设data是你的原始数据集 df_ref1 = data.groupby(['ref_date'])['fuel'].value_counts().unstack() fig, ax = plt.subplots(figsize=(6,4), dpi=200) df_ref1.plot(ax=ax, kind='bar', stacked=True) # 核心:生成自定义刻度标签 date_labels = [] for date in df_ref1.index: # 判断是否为1月,是则显示年份+月份,否则只显示月份 if date.month == 1: date_labels.append(date.strftime('%Y/%m')) else: date_labels.append(date.strftime('%m')) # 设置X轴刻度标签 ax.set_xticklabels(date_labels) # 其余原有设置保留 ax.set_title('Distribuição de tipo de combustível') ax.spines[['top','right', 'left']].set_visible(False) ax.set_xlabel('') plt.xticks(rotation=45, ha='right') ax.legend(['Gasolina','Disel', 'Álcool'], bbox_to_anchor=(.85, .95, 0, 0), shadow=False, frameon=False) plt.tight_layout() plt.show()
关键说明
- 遍历
df_ref1的datetime索引,用strftime根据月份生成对应格式的标签 - 用
ax.set_xticklabels()直接替换分类轴的标签,避免了把整数索引当成时间戳解析的问题 - 保留了你原有绘图的所有样式设置,仅修改刻度标签逻辑
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

