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

如何在00:00-23:59的24小时坐标轴绘制每日数据(无重复时间)

解决Seaborn折线图X轴时间重复的问题

问题原因

你当前代码里的TIME列是将每天的时间转为字符串,不同日期的同一时间(比如11月1日和11月2日的00:00)会被当作不同的X轴数据点,但显示文本完全一致,导致视觉上出现时间重复。要让X轴仅显示00:00到23:59的唯一时间,需要把时间转换成一天内的连续数值/时间差类型,让Matplotlib识别这些是同一个刻度位置。

解决方案

下面是修改后的完整代码,核心是将时间转为一天内的分钟数,再自定义X轴标签格式:

import random
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.ticker as ticker

random.seed(0)

df = pd.DataFrame({'DATE_TIME': pd.date_range('2022-11-01', '2022-11-06 23:00:00', freq='20min'),
                   'ID': [random.randrange(1, 3) for n in range(430)]})
df['VALUE1'] = [random.uniform(110, 160) for n in range(430)]
df['VALUE2'] = [random.uniform(50, 80) for n in range(430)]
df['INSPECTION'] = df['DATE_TIME'].dt.day

df['MODE'] = np.select([df['INSPECTION'] == 1, df['INSPECTION'].isin([2, 3])], ['A', 'B'], 'C')
# 替换原TIME列:计算一天内的分钟数,作为连续X轴值
df['MINUTES_OF_DAY'] = df['DATE_TIME'].dt.hour * 60 + df['DATE_TIME'].dt.minute

df['TIMEINTERVAL'] = df.DATE_TIME.diff().astype('timedelta64[m]')
df['TIMEINTERVAL'] = df['TIMEINTERVAL'].fillna(0)


def to_day_period(s):
    bins = ['0', '06:00:00', '13:00:00', '18:00:00', '23:00:00', '24:00:00']
    labels = ['Nighttime', 'Daytime', 'Daytime', 'Nighttime', 'Nighttime']

    return pd.cut(
        pd.to_timedelta(s),
        bins=list(map(pd.Timedelta, bins)),
        labels=labels, right=False, ordered=False
    )


# 保留原TIME字符串用于时段计算,不影响绘图
df['TIME'] = df['DATE_TIME'].dt.time.astype('str')
df['TIME_OF_DAY'] = to_day_period(df['TIME'])
df_monthly = df

# ++++++++++++++++++++++++++++++++ 绘图部分 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
df_id = df[df.ID==1]
sns.set_style('darkgrid')
sns.set(rc={'figure.figsize':(14,8)})

# 使用MINUTES_OF_DAY作为X轴,确保同一时间点对应同一个刻度
ax = sns.lineplot(data=df_id, x='MINUTES_OF_DAY', y='VALUE1',
                  hue='INSPECTION', palette='viridis',
                  legend='full', lw=3)

# 自定义X轴刻度:将分钟数转换为HH:MM格式
def format_minutes_to_time(x, pos):
    hours = int(x // 60)
    minutes = int(x % 60)
    return f"{hours:02d}:{minutes:02d}"

# 设置X轴主刻度间隔为120分钟(2小时),可根据需求调整
ax.xaxis.set_major_locator(ticker.MultipleLocator(120))
ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_minutes_to_time))

# 限制X轴范围为0-1440分钟(完整24小时)
ax.set_xlim(0, 1440)

plt.legend(bbox_to_anchor=(1, 1))
plt.ylabel('VALUE1')
plt.xlabel('TIME')
plt.show()

关键改动说明

  • 新增MINUTES_OF_DAY列:将每天的时间转换为0-1439的分钟数,不同日期的同一时间会对应同一个数值,Matplotlib会自动将它们归到同一个X轴刻度上。
  • 用FuncFormatter将分钟数转换为HH:MM格式的标签,保证X轴显示易读的时间文本。
  • 设置xlim(0,1440)确保X轴严格限制在24小时范围内,避免超出边界的刻度。

修改后X轴只会显示00:00到23:40的唯一时间标签,不会再出现重复问题。

内容的提问来源于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 03:05:44