matplotlib绘制numpy datetime时序图触发无效日期值报错的排查
时序观测-模拟值对比绘图的异常排查
基础场景
需要在matplotlib同一张图上绘制某时序参数的两类序列对比:
- 观测数据:从Excel文件通过openpyxl读取,转换为pandas DataFrame格式后提取
- 模拟数据:模拟输出的时间为距初始时刻的累计天数值,通过固定代码块转换为numpy datetime类型:
delt = get_simulated_time() t0 = np.datetime64('2004-01-01T00:00:00') tsim = t0 + np.asarray(delt).astype('timedelta64[D]')
实际绘图代码逻辑
df = obs_data_df.query("block=='blk-7'") pobs = df['pres'] tobs = df['date'] tobs = np.array(tobs, dtype='datetime64') print(type(tobs), np.min(tobs), np.max(tobs)) axs.plot(tobs, pobs, '.', color='g', label='blk-7, obs', markersize=8) tsim = np.array(curr_sim_obj.tsim, dtype='datetime64') print(type(tsim), np.min(tsim), np.max(tsim)) axs.plot(tsim, curr_sim_obj.psim[:, 0], '-', color='g', label='blk-7, sim', linewidth=1)
异常表现
- 打印校验显示两类时间数组均为numpy.ndarray类型,观测时间范围为2004-06-01至2020-06-01,模拟时间范围为2004-01-01至2020-07-20,类型、时间范围逻辑完全连续合理
- 绘图时matplotlib抛出ValueError,提示视图下限值-36907.706903627106小于1,属于无效的Matplotlib日期值。这类报错的典型触发场景是:向已经被设置为日期单位的坐标轴传入非日期类型数值
- 执行
print(np.dtype(tsim), np.min(tobs), np.max(tobs))进一步排查类型信息时,又触发TypeError提示数据类型无法识别,过程中容易混淆Python、pandas、numpy三者的日期类型处理规则
问题定位与根因
逐行精简代码复现缩小排查范围时,发现绘图流程中残留了早期测试用的随机散点代码:
axs.plot(10*np.random.randn(100), 10*np.random.randn(100), 'o')
- 这段残留代码的执行逻辑是:先向同一个坐标轴传入范围在-10到10之间的普通浮点数作为x轴数据,将x轴初始化为适配普通数值的线性坐标轴;后续传入datetime类型时间数组绘图时,matplotlib未正确触发日期坐标轴的自动适配逻辑,反而将日期值转换为数值后与之前的随机值范围做匹配,最终触发越界无效值报错
- 移除这段残留测试代码后,报错完全消失,两类时间序列可正常叠加绘制
多来源时序同图绘制的实操注意点
- 同一坐标轴上尽量避免混杂传入普通数值与datetime类型的x轴数据,防止matplotlib自动适配轴类型时出现逻辑混乱
- 跨来源的时间数组在绘图前统一转换为numpy.datetime64类型,减少pandas Timestamp、Python原生datetime、numpy datetime64三者之间的类型转换兼容问题
- 排查类似日期轴报错时,优先逐行注释测试代码,定位是否有残留的早期绘图逻辑干扰坐标轴的类型初始化
内容的提问来源于stack exchange,提问作者PetGriffin
相关产品推荐
相关产品推荐

