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

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也无效,求修复方案。


问题原因

  1. 自动生成的minor刻度数量和日期天数不匹配,用zip强行配对必然导致错位、漏标签。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:30:50