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
相关产品推荐
相关产品推荐

