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

如何按时间段为Matplotlib时序图背景着色并添加时段标签

解决时序图夜间背景与标签对齐问题

1. 先确保时间数据格式正确

首先要把数据集的时间列转换成Pandas的datetime64类型,这是解决X轴偏移的核心前提——非datetime类型的时间会导致matplotlib无法正确解析时间轴,直接引发错位:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# 假设数据集含'timestamp'列,替换为你的时间列名
df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.set_index('timestamp').sort_index()

2. 生成合规的夜间时间段区间

处理跨天的夜间区间(18:00至次日06:00),同时裁剪超出数据集时间范围的无效区间,避免背景色块溢出:

# 获取数据覆盖的所有日期
dates = pd.date_range(start=df.index.min().date(), end=df.index.max().date(), freq='D')

night_intervals = []
for date in dates:
    night_start = pd.Timestamp(date) + pd.Timedelta(hours=18)
    night_end = pd.Timestamp(date) + pd.Timedelta(hours=30)  # 次日6:00等价于当天+30小时
    # 裁剪到数据集实际时间范围
    clip_start = max(night_start, df.index.min())
    clip_end = min(night_end, df.index.max())
    if clip_start < clip_end:
        night_intervals.append((clip_start, clip_end))

3. 绘制时序图并叠加夜间背景

先画Seaborn折线图,再用axvspan添加深色透明背景,直接传入datetime对象即可让matplotlib自动匹配坐标轴位置:

fig, ax = plt.subplots(figsize=(12, 6))
# 替换'value_column'为你的数值列名
sns.lineplot(data=df, x=df.index, y='value_column', ax=ax)

# 添加夜间背景色块
for start, end in night_intervals:
    ax.axvspan(start, end, color='#2d2d2d', alpha=0.2)

4. 添加居中的Day/Night标签

用坐标轴相对定位确保标签垂直居中,同时计算区间中点保证水平居中,彻底解决标签位置偏移问题:

# 添加Night标签
for start, end in night_intervals:
    mid_point = start + (end - start) / 2
    # get_xaxis_transform()让y坐标基于坐标轴比例(0=底部,1=顶部),不受数据y值影响
    ax.text(mid_point, 0.5, 'Night', color='white', fontsize=12,
            ha='center', va='center', transform=ax.get_xaxis_transform(),
            bbox=dict(facecolor='#2d2d2d', alpha=0.6, edgecolor='none'))

# 生成日间区间并添加Day标签
day_intervals = []
for date in dates:
    day_start = pd.Timestamp(date) + pd.Timedelta(hours=6)
    day_end = pd.Timestamp(date) + pd.Timedelta(hours=18)
    clip_start = max(day_start, df.index.min())
    clip_end = min(day_end, df.index.max())
    if clip_start < clip_end:
        day_intervals.append((clip_start, clip_end))

for start, end in day_intervals:
    mid_point = start + (end - start) / 2
    ax.text(mid_point, 0.5, 'Day', color='#2d2d2d', fontsize=12,
            ha='center', va='center', transform=ax.get_xaxis_transform())

5. 优化X轴显示(可选)

如果时间标签拥挤,可调整格式提升可读性:

import matplotlib.dates as mdates
ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d %H:%M'))
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

核心问题对应解法

  • X轴偏移:强制时间列为datetime64类型,让matplotlib自动处理时间轴映射,避免手动数值转换出错。
  • 背景色异常:通过裁剪区间确保色块仅在数据集时间范围内显示,杜绝溢出或错位。
  • 标签位置不符:使用坐标轴相对定位get_xaxis_transform()固定垂直位置,结合区间中点保证水平居中。

内容的提问来源于stack exchange,提问作者dsapprentice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 15:55:27