Matplotlib绘制Pandas datetime64轴时高亮周末及标签同步问题
问题根源
- 原代码存在三个核心错误导致标签偏移:
- 代码中
plot.get_xticks()的plot变量未定义,实际取到的刻度值和底部x轴的日期序列没有绑定,刻度数量也可能和df.weekend的长度不匹配 - 顶部twiny轴没有和底部x轴的日期范围、刻度规则做绑定,直接赋值的标签和日期没有一一对应
- 没有统一日期转星期的计算规则,无法保证周一为0的输出结果正确
- 代码中
修正实现方案
直接基于底部x轴的日期值生成对应的星期标签,同时补充周末高亮逻辑,完整代码如下:
from matplotlib.dates import DayLocator, DateFormatter import matplotlib.dates as mdates import matplotlib.pyplot as plt import pandas as pd # 先统一计算星期:*dt.weekday默认周一为0,刚好符合你的要求* time_bookings['weekday'] = time_bookings['ymd'].dt.weekday # 生成星期文本映射,可根据需求调整显示内容 weekday_map = {0:'周一',1:'周二',2:'周三',3:'周四',4:'周五',5:'周六',6:'周日'} time_bookings['weekday_label'] = time_bookings['weekday'].map(weekday_map) fig1, ax1 = plt.subplots(figsize=(20,8)) # 底部x轴绘图 ax1.plot(time_bookings.ymd, time_bookings.bookings, color="r", marker="o") # 底部x轴配置 ax1.grid(axis='x') ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y')) ax1.xaxis.set_major_locator(mdates.DayLocator()) ax1.set_title("Mean daily bookings") ax1.set_ylabel("Number of Bookings") ax1.tick_params(axis='x', rotation=90) ax1.set_xlabel("Time (Days)") # 高亮周末:遍历所有日期,给周六周日加半透明背景 for idx, row in time_bookings.iterrows(): if row['weekday'] >=5: # 周六为5、周日为6,均属于周末 ax1.axvspan(mdates.date2num(row['ymd'])-0.5, mdates.date2num(row['ymd'])+0.5, color='gray', alpha=0.2) # 顶部星期轴配置,和底部轴完全同步 ax2 = ax1.twiny() # 强制双轴范围一致,避免两端偏移 ax2.set_xlim(ax1.get_xlim()) ax2.set_xticks(ax1.get_xticks()) # 把底部刻度的数值转成日期,再匹配对应的星期标签,保证一一对应 xtick_dates = mdates.num2date(ax1.get_xticks()) xtick_labels = [weekday_map[d.weekday()] for d in xtick_dates] ax2.set_xticklabels(xtick_labels) ax2.set_xlabel("星期") plt.tight_layout() plt.show()
关键修正说明
- 用
ax1.get_xlim()同步双x轴的范围,避免坐标轴边界错位 - 不再直接用DataFrame的列作为标签,而是基于底部轴的刻度值实时转换为星期,完全消除偏移问题
- 新增的
axvspan逻辑自动识别周末并添加半透明灰色高亮,满足你的场景需求 - 统一用pandas自带的
dt.weekday计算星期,默认周一为0,和你设定的规则完全匹配
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

