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

Matplotlib绘制同一数据时出现平线与正确线条差异问题

问题:同一初始数据在不同图表中显示异常

同一数据FTBS_nonlin_out[0.0](蓝色线条)在plot2中显示为真实波形,在plot1中却显示为平线,已在Python3.8、3.10及多个内核环境测试,仍无法定位异常原因。

相关代码实现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#Global Variables
#==============
L, J = 100, 100
dx = L/J
c = 1 #velocity

shape = lambda x: 5*np.sin(x/np.pi)
feature = slice(40,50)
times = (0,4,8,20)

#functions
#==============
def step(func, signal:pd.DataFrame, steps:tuple|list|np.ndarray|pd.DataFrame, *args, dt=0.5, **kwargs):
    for n in np.round(np.arange(0, steps[-1]+dt, dt), 3):
        t1 = np.round(n+dt,3)
        signal[t1] = np.nan
        data = func(signal, n, t1, dt, *args, **kwargs)
    return data

def _0State(feature:slice, func): #Creates the innitial signal
    signal = np.zeros(J+1)
    signal[feature] = [func(element) for element in list(range(len(signal[feature])))]
    signal = pd.DataFrame(signal, index=np.linspace(0,L,J+1), columns=[0.0])
    signal.index.name = 'x'
    return signal

#=====================================
def FTBS_nonlin(signal:pd.DataFrame, t, t1, dt):  #u_i^{n+1} = u_{i}^{n} - u_{i}^{n} \frac{\Delta t}{\Delta x}(u_{i}^{n} - u_{i-1}^{n})
    for i, row in signal.iloc[1:].iterrows(): 
        signal.loc[i, t1] = row[t] - row[t] * (dt/dx) * (row[t] - signal.loc[i-1,t])
    return signal

signal = _0State(feature, shape)
FTBS_nonlin_out = step(FTBS_nonlin, signal.copy(), times)

fig, ax1 = plt.subplots()
ax1.set_xlabel('x')
ax1.set_ylabel('θ')
ax1.plot(FTBS_nonlin_out[0.0])
ax1.plot(FTBS_nonlin_out[4])
plt.legend()
plt.title('plot')
plt.show()

fig, ax1 = plt.subplots()
ax1.set_xlabel('x')
ax1.set_ylabel('θ')
ax1.plot(FTBS_nonlin_out[0.0])
ax1.plot(FTBS_nonlin_out[2])
plt.legend()
plt.title('plot2')
plt.show()

原因分析

  1. 数值耗散导致幅值快速衰减:使用的FTBS(迎风差分)格式本身存在数值耗散,叠加非线性方程迭代后,初始波形的幅值会随时间急剧衰减。到t=4时,FTBS_nonlin_out[4.0]的数据幅值已趋近于0,而初始数据FTBS_nonlin_out[0.0]的幅值最大为5。
  2. y轴范围自动压缩:matplotlib会根据所有绘制数据自动调整坐标轴范围。plot1中同时绘制了幅值接近0的t=4数据和幅值为5的初始数据,y轴范围被压缩到接近0的区间,导致初始数据的波形被挤压成看似平线的状态;而plot2中t=2的数据幅值尚未衰减到极小,y轴范围能覆盖初始数据的幅值,因此波形正常显示。

解决办法

  • 显式指定y轴范围,确保初始数据幅值在显示区间内:在plot1代码中添加ax1.set_ylim(-0.5, 5.5);
  • 给绘图添加标签,明确图例对应关系:比如ax1.plot(FTBS_nonlin_out[0.0], label='t=0')、ax1.plot(FTBS_nonlin_out[4.0], label='t=4'),再调用plt.legend();
  • 使用正确的浮点数列名访问数据:将FTBS_nonlin_out[4]改为FTBS_nonlin_out[4.0],FTBS_nonlin_out[2]改为FTBS_nonlin_out[2.0],避免索引匹配错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:57:47