Matplotlib如何在X轴高亮周末?标签颜色异常问题求助
在Matplotlib中高亮时间序列X轴的周末标签
我有一段多日时间序列数据(能源使用数据),需要在Matplotlib图表的X轴高亮显示周末。编写了如下代码:
import pandas as pd import matplotlib.pyplot as plt import datetime import random # 创建模拟数据 start = datetime.datetime(2022,10,22,0,0) finish = datetime.datetime(2022,11,7,0,0) def randomWalk(): i = 0 while True: i = i + random.random() - 0.5 yield i s = pd.Series({i: next(randomWalk()) for i in pd.date_range(start, finish, freq='h')}) # 绘图 plt.figure(figsize=[12, 8]) s.plot() # 根据星期几设置标签颜色 for label, day in zip(plt.gca().xaxis.get_ticklabels(which='minor'), pd.date_range(start, finish, freq='d')): label.set_color('red' if day.weekday() > 4 else 'black')
运行后出现异常:两个周末标签颜色错位,第三个周末完全未显示。查看标签对象的X坐标为无意义整数,使用DateFormatter也无效,求修复方案。
问题原因
- 自动生成的
minor刻度数量和日期天数不匹配,用zip强行配对必然导致错位、漏标签。 - Matplotlib内部将日期存储为浮点数(从基准日开始计算的天数),直接读取标签X坐标无法对应真实日期,自然没法准确判断周末。
修复代码
import pandas as pd import matplotlib.pyplot as plt import datetime import random from matplotlib.dates import DateFormatter, DayLocator # 创建模拟数据 start = datetime.datetime(2022,10,22,0,0) finish = datetime.datetime(2022,11,7,0,0) def randomWalk(): i = 0 while True: i = i + random.random() - 0.5 yield i s = pd.Series({i: next(randomWalk()) for i in pd.date_range(start, finish, freq='h')}) # 初始化画布和轴对象,方便后续控制 fig, ax = plt.subplots(figsize=[12, 8]) s.plot(ax=ax) # 强制X轴每天显示一个刻度,确保每个日期都有对应标签 ax.xaxis.set_major_locator(DayLocator()) # 设置日期显示格式,避免标签混乱 ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d')) # 遍历所有刻度标签,判断是否为周末并设置颜色 for label in ax.xaxis.get_ticklabels(): # 将Matplotlib内部的日期浮点数转换为真实datetime对象 date = datetime.datetime.fromordinal(int(label.get_position()[0])) # weekday()返回0=周一,6=周日,大于4就是周六/周日 if date.weekday() > 4: label.set_color('red') else: label.set_color('black') # 旋转标签防止重叠,调整布局让显示更美观 plt.xticks(rotation=45) plt.tight_layout() plt.show()
关键改动说明
- 用
DayLocator()手动指定每日刻度,彻底解决自动刻度数量不匹配的问题。 - 通过
datetime.fromordinal()将内部日期浮点数转换为真实日期,准确判断周末。 - 增加标签旋转和布局调整,提升图表可读性。
内容的提问来源于stack exchange,提问作者CharlesW
相关产品推荐
相关产品推荐

