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

天气数据绘图x轴时间戳格式化异常及定制需求求助

解决Matplotlib天气数据绘图的X轴格式化问题(附完整修复代码)

哇,我太懂这种调时间轴调得头大的感觉了!你遇到的ValueError: year is out of range十有八九是Unix时间戳单位不匹配导致的——很多时候我们拿到的天气数据时间戳是毫秒级的,但matplotlib的mdates默认认秒级的epoch时间,直接喂毫秒的话会被解析成几十万年以后的时间,自然报错。

结合你的需求(30分钟刻度、每小时虚线网格、UTC时区00:00显示日期),我整理了一套亲测有效的解决方案:

核心问题定位

你的时间戳是Unix epoch格式,但如果是毫秒级(比如1690000000000),直接传给mdates会触发年份溢出错误。第一步必须把时间戳转换成UTC时区的datetime对象。

完整修复代码示例

假设你的样本数据是包含timestamp(Unix时间戳)和temperature(温度)的列表/数组,代码如下:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime, timezone
import numpy as np

# ---------------------- 模拟你的样本数据 ----------------------
# 注意:这里用毫秒级时间戳模拟常见的天气数据格式
timestamps_ms = np.arange(1690000000000, 1690100000000, 1800000)  # 每30分钟一个数据点
temperatures = np.random.randn(len(timestamps_ms)) * 5 + 25

# ---------------------- 关键:时间戳转换为UTC datetime ----------------------
# 先判断时间戳单位:如果是毫秒就除以1000,秒级就直接用
# 可以通过打印第一个时间戳的长度判断:13位是毫秒,10位是秒
if len(str(timestamps_ms[0])) == 13:
    timestamps_s = timestamps_ms / 1000
else:
    timestamps_s = timestamps_ms

# 转换为UTC时区的datetime对象
utc_dates = [datetime.fromtimestamp(ts, timezone.utc) for ts in timestamps_s]

# ---------------------- 绘图与X轴格式化 ----------------------
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(utc_dates, temperatures, label="Temperature (°C)")

# 1. 设置X轴刻度:每30分钟一个标记
ax.xaxis.set_major_locator(mdates.MinuteLocator(interval=30))

# 2. 设置X轴标签:自定义格式化——00:00显示日期,其他显示HH:MM
def custom_date_formatter(x, pos):
    date = mdates.num2date(x, tz=timezone.utc)
    if date.hour == 0 and date.minute == 0:
        # 00:00位置显示日期(UTC)
        return date.strftime("%Y-%m-%d")
    else:
        # 其他时间显示HH:MM
        return date.strftime("%H:%M")

ax.xaxis.set_major_formatter(plt.FuncFormatter(custom_date_formatter))

# 3. 设置每小时的垂直虚线网格
ax.xaxis.set_minor_locator(mdates.HourLocator(interval=1))
ax.grid(True, which='minor', axis='x', linestyle='--', color='gray', alpha=0.5)
ax.grid(True, which='major', axis='y', linestyle='-', color='lightgray')

# 4. 旋转X轴标签避免重叠
plt.xticks(rotation=45, ha='right')

ax.set_ylabel("Temperature (°C)")
ax.set_title("Weather Data (UTC Time)")
ax.legend()
plt.tight_layout()
plt.show()

关键细节说明

  • 时间戳转换:一定要确认是秒级还是毫秒级,这是解决year is out of range的核心!
  • 自定义格式化器:通过FuncFormatter判断当前时间是否为00:00,分别显示日期或时间,完美匹配你的需求。
  • 网格设置:用HourLocator作为次要定位器,设置虚线网格,既满足每小时的分隔,又不干扰30分钟的主刻度。
  • UTC时区:全程用timezone.utc确保时间显示正确,避免本地时区干扰。

排查小技巧

如果还是报错,你可以先打印几个转换后的utc_dates对象,确认年份是正常的(比如2023/2024),如果年份是几千甚至几万,那肯定是时间戳单位没转对!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:24:22