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

DateFormatter显示异常:双Y轴次Y轴时间全为00:00:00问题排查

问题:双Y轴图表次Y轴时间显示异常(全部为00:00:00)

我有一个双Y轴图表,希望将第二个Y轴以24小时格式(HH:MM:SS)显示睡眠时长,但生成的图表中该轴所有时间都显示为00:00:00,不过柱状图的对应数值显示正常。

原代码:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
from matplotlib.dates import DateFormatter

rc('mathtext', default='regular')
 
# 创建数据集
x = Trend1['Date']
SleepDisturbance = Trend1['DisturbancesCount']
Movements = Trend1['AverageMovementCount']
Duration = Trend1['DurationInNumbers']


# 创建画布
w=0.5
fig, ax = plt.subplots(figsize=(20,10)) 

# 绘制柱状图
ax.bar(x, SleepDisturbance, label='睡眠干扰次数')
ax.bar(x, Movements, label='平均活动次数')
 
# 创建次Y轴
ax2 = ax.twinx()
ax2.plot(x, Duration, '-r', label='睡眠时长')


# 添加标题
plt.title('睡眠干扰、平均活动次数与睡眠时长对比',
          fontweight="bold")
 
# 添加图例
ax.legend(loc='upper left', fontsize=20)
ax2.legend(loc='upper right', fontsize=20)
 
# 添加网格
ax.grid()
 
# 添加轴标签
ax.set_xlabel("日期",fontsize=18, fontweight='bold')
ax.set_ylabel("次数", fontsize=18, fontweight='bold')
ax2.set_ylabel("睡眠时长", fontsize=18, fontweight='bold')
 
# 设置Y轴范围
ax.set_ylim(0, 15)

hh_mm_ss = DateFormatter('%H:%M:%S')
ax2.yaxis.set_major_formatter(hh_mm_ss)

# 保存并显示图表
plt.savefig('睡眠数据对比图.png',bbox_inches='tight')
plt.show()

问题原因:

DateFormatter是Matplotlib专门用于日期时间对象/时间戳数据的格式化工具,但你的Duration是普通数值类型(比如代表分钟、秒的数字),直接用它格式化时,数值会被当作从1970-01-01 00:00:00开始的时间戳偏移量,小数值对应的时间就是0点左右,所以全部显示为00:00:00。

解决方案:

需要自定义一个格式化函数,将数值类型的时长转换成HH:MM:SS格式,用FuncFormatter替代DateFormatter。

修改后的关键代码:

首先导入FuncFormatter:

from matplotlib.ticker import FuncFormatter

然后根据Duration的实际单位选择对应的格式化函数:

  • 如果Duration单位是分钟:
def format_duration_minutes(x, pos):
    hours = int(x // 60)
    minutes = int(x % 60)
    seconds = int((x - int(x)) * 60)
    return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
  • 如果Duration单位是秒:
def format_duration_seconds(x, pos):
    hours = int(x // 3600)
    minutes = int((x % 3600) // 60)
    seconds = int(x % 60)
    return f"{hours:02d}:{minutes:02d}:{seconds:02d}"

最后替换原有的DateFormatter代码:

# 替换hh_mm_ss = DateFormatter(...)及后续设置代码
ax2.yaxis.set_major_formatter(FuncFormatter(format_duration_minutes))  # 按实际单位选对应函数

修改后的完整代码示例:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
from matplotlib.ticker import FuncFormatter

rc('mathtext', default='regular')
 
# 创建数据集
x = Trend1['Date']
SleepDisturbance = Trend1['DisturbancesCount']
Movements = Trend1['AverageMovementCount']
Duration = Trend1['DurationInNumbers']


# 创建画布
w=0.5
fig, ax = plt.subplots(figsize=(20,10)) 

# 绘制柱状图
ax.bar(x, SleepDisturbance, label='睡眠干扰次数')
ax.bar(x, Movements, label='平均活动次数')
 
# 创建次Y轴
ax2 = ax.twinx()
ax2.plot(x, Duration, '-r', label='睡眠时长')


# 添加标题
plt.title('睡眠干扰、平均活动次数与睡眠时长对比',
          fontweight="bold")
 
# 添加图例
ax.legend(loc='upper left', fontsize=20)
ax2.legend(loc='upper right', fontsize=20)
 
# 添加网格
ax.grid()
 
# 添加轴标签
ax.set_xlabel("日期",fontsize=18, fontweight='bold')
ax.set_ylabel("次数", fontsize=18, fontweight='bold')
ax2.set_ylabel("睡眠时长", fontsize=18, fontweight='bold')
 
# 设置Y轴范围
ax.set_ylim(0, 15)

# 自定义时长格式化函数(假设Duration单位是分钟)
def format_duration_minutes(x, pos):
    hours = int(x // 60)
    minutes = int(x % 60)
    seconds = int((x - int(x)) * 60)
    return f"{hours:02d}:{minutes:02d}:{seconds:02d}"

# 应用格式化函数到次Y轴
ax2.yaxis.set_major_formatter(FuncFormatter(format_duration_minutes))

# 保存并显示图表
plt.savefig('睡眠数据对比图.png',bbox_inches='tight')
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:56:01