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

Python如何绘制y轴范围为20点至次日12点的夜间入睡时间图

解决方案

问题根因

你直接使用mdates.datestr2num转换入睡时间时,返回的数值是以当日0点为基准的浮点值,0点的数值会小于23点,导致跨天的入睡时间(比如00:23)在y轴上显示位置早于22点、23点,同时原生时间轴也无法直接设置20点到次日12点的跨天区间。

实现代码

核心思路是对入睡时间做数值偏移,将0点到12点的时间统一加24小时,让时间在数值维度符合你要的顺序,再自定义y轴的显示标签即可:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import dates as mdates

# 数据预处理
data = pd.read_csv("sleepdata.csv", sep=";")
data["Date"] = pd.to_datetime(data["Date"])

# 将入睡时间转为偏移小时值:小于12点的时间加24小时,保证23点 < 0点 < 12点的数值顺序
def calc_offset_hour(time_str):
    time_obj = pd.to_datetime(time_str).time()
    total_h = time_obj.hour + time_obj.minute/60 + time_obj.second/3600
    return total_h + 24 if total_h < 12 else total_h

data["sleep_start_offset"] = data["Start"].apply(calc_offset_hour)

# 绘图配置
fig, ax = plt.subplots(figsize=(9,5))
ax.plot(mdates.date2num(data["Date"]), data["sleep_start_offset"], marker="o", linewidth=2)

# x轴日期格式配置
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
plt.xticks(rotation=30)

# y轴自定义刻度与标签
y_ticks = range(20, 37)
y_labels = [f"{h}:00" if h < 24 else f"{h-24:02d}:00" for h in y_ticks]
ax.set_yticks(y_ticks)
ax.set_yticklabels(y_labels)
ax.set_ylim(20, 36)

# 基础样式配置
ax.set_xlabel("日期")
ax.set_ylabel("入睡时间")
plt.tight_layout()
plt.show()

方案说明

  • 不需要修改matplotlib的原生时间轴规则,实现逻辑简单易懂
  • 偏移后的数值可以直接用于后续的睡眠规律统计、异常值识别等计算场景
  • 刻度标签可根据需要灵活调整,比如要显示半小时刻度只要修改y_ticks的生成规则即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:18:01