
同一组数据在 matplotlib 中绘制时,有时显示为几乎不可见的扁平线,实则是因坐标轴范围过大导致细节被压缩;调整 y 轴范围或使用 `plt.tight_layout()`、`ax.set_ylim()` 即可恢复真实形态。
该问题本质并非数据异常或绘图逻辑错误,而是 Matplotlib 自动缩放(autoscaling)机制在多条曲线量级差异极大时失效 所致。观察原始代码中两个子图:
- plot1 同时绘制 FTBS_nonlin_out[0.0](初始状态,幅值约 ±5)与 FTBS_nonlin_out[4](经数值迭代后,在某些位置产生剧烈震荡或数值溢出),后者可能因 FTBS 格式在非线性情形下缺乏稳定性,导致局部值爆炸(如答案指出:y 轴达 −2×10¹⁸ 量级);
- plot2 绘制的是 FTBS_nonlin_out[0.0] 与 FTBS_nonlin_out[2],后者尚未严重发散,整体动态范围较小(≈ −25 到 5),因此初始正弦波形清晰可见。
此时,Matplotlib 为容纳所有数据点,将 y 轴设为覆盖最大/最小值的全局范围。当某条曲线存在极端离群值(如数值不稳定性引发的 inf、极大负数),其余曲线在其映射下便退化为视觉上的一条“水平线”。
✅ 验证与修复方法如下:
-
检查数据实际范围(推荐前置调试):
print("FTBS_nonlin_out[0.0]:", FTBS_nonlin_out[0.0].min(), FTBS_nonlin_out[0.0].max()) print("FTBS_nonlin_out[4]:", FTBS_nonlin_out[4].min(), FTBS_nonlin_out[4].max()) -
强制设定合理 y 轴范围(最直接有效):
ax1.plot(FTBS_nonlin_out[0.0], label='t=0.0') ax1.plot(FTBS_nonlin_out[4], label='t=4.0') ax1.set_ylim(-30, 10) # 根据物理意义或初值范围设定 ax1.legend()
-
过滤异常值,避免污染坐标轴(适用于含 NaN/inf 的场景):
# 安全绘图:仅绘制有限值 valid_0 = FTBS_nonlin_out[0.0].replace([np.inf, -np.inf], np.nan).dropna() valid_4 = FTBS_nonlin_out[4].replace([np.inf, -np.inf], np.nan).dropna() ax1.plot(valid_0.index, valid_0.values, label='t=0.0') ax1.plot(valid_4.index, valid_4.values, label='t=4.0')
⚠️ 注意事项:
- 此现象常掩盖更深层的数值不稳定性问题。本例中 FTBS_nonlin 函数实现的是显式迎风格式(FTBS),但其应用于非线性对流项 $ u \frac{\partial u}{\partial x} $ 时,需满足 CFL 条件 $ c \frac{dt}{dx} \leq 1 $。当前 c=1, dt=0.5, dx=1.0(因 L=J=100 → dx=1),CFL 数为 0.5,理论上稳定;但若迭代中 u 增大(如局部陡增),实际局部 CFL 可能远超 1,引发振荡与溢出。建议监控 signal[t] 每步的最大绝对值,或改用 TVD 格式、添加人工粘性。
- 不要依赖 plt.show() 默认缩放——尤其在科研绘图中,显式控制坐标轴是良好实践。
总结:看似“绘图 bug”,实为数值行为 + 可视化策略的双重体现。养成「先查数据、再设范围、后分析机理」的习惯,可快速定位并解决此类“扁平线”陷阱。










