Van der Pol振荡器类开发求助:DataFrame模拟与绘图异常
Van der Pol振荡器类错误修复
错误分析
- DataFrame构建问题:
- 未以时间作为索引,导致绘图X轴显示数据点序号而非实际时间
- 使用自定义类实例作为列名,造成列标识混乱且无法正常索引
- 未在每次调用
get_sim_data时清空旧数据,多次调用会出现数据叠加 np.linspace的长度计算因浮点数精度问题,可能缺失最后一个时间点(30.0)
- 绘图逻辑问题:
- 未根据
tmin和tmax筛选目标时间范围,直接绘制全部数据 - 未使用时间轴作为X轴,默认用DataFrame索引(0-3000)替代
- 缺少图表基本元素(轴标签、图例、标题),结果展示不直观
- 未根据
修复后的代码
from scipy.integrate import solve_ivp import numpy as np import pandas as pd import matplotlib.pyplot as plt class VanDerPol: def __init__(self): self.oscillators = [] self.sim_time = None # 存储模拟时间数组 self.df = pd.DataFrame() def add_oscillator(self, mu, x0=1, y0=0): # 用字典存储参数,替代内部类,简化访问 self.oscillators.append({"mu": mu, "x0": x0, "y0": y0}) def delete_oscillator(self, i): if 0 <= i < len(self.oscillators): self.oscillators.pop(i) else: print(f"索引{i}超出振荡器列表范围") def get_sim_data(self, duration=30.0, dt=0.01): # 生成准确的时间数组,确保包含duration终点 self.sim_time = np.arange(0.0, duration + dt, dt) # 清空旧数据,重新初始化DataFrame self.df = pd.DataFrame(index=self.sim_time) for osc in self.oscillators: mu = osc["mu"] # 定义Van der Pol微分方程,避免闭包变量问题 def vdp(t, z): x, y = z return [y, mu * (1 - x**2) * y - x] # 求解微分方程 sol = solve_ivp(vdp, [0, duration], [osc["x0"], osc["y0"]], t_eval=self.sim_time) # 以mu值作为列名,存储位移x的模拟结果 self.df[f"mu={mu}"] = sol.y[0] return self.df def plot(self, tmin=0.0, tmax=30.0): # 筛选指定时间范围的数据 mask = (self.df.index >= tmin) & (self.df.index <= tmax) filtered_df = self.df.loc[mask] # 绘制图表 plt.figure(figsize=(10, 6)) for col in filtered_df.columns: plt.plot(filtered_df.index, filtered_df[col], label=col) plt.xlabel("时间 t") plt.ylabel("位移 x") plt.title("Van der Pol振荡器位移随时间变化") plt.legend() plt.grid(True) plt.show() # 测试代码 vdp = VanDerPol() vdp.add_oscillator(1.0) # 添加mu=1.0的振荡器 vdp.add_oscillator(3.0) # 添加mu=3.0的振荡器 vdp.add_oscillator(2.0) # 添加mu=2.0的振荡器 vdp.delete_oscillator(1) # 删除mu=3.0的振荡器 # 获取模拟数据并打印前5行 sim_data = vdp.get_sim_data(dt=0.01) print("模拟数据前5行:") print(sim_data.head()) # 绘制10-30秒的结果 vdp.plot(tmin=10.0, tmax=30.0)
关键修复说明
- 参数存储优化:用字典替代内部类,简化参数访问,避免类实例作为列名的混乱
- 时间轴修正:使用
np.arange生成时间数组,确保包含终点值,长度准确 - DataFrame重构:以时间为索引,用
mu=X作为列名,数据结构清晰,便于筛选和绘图 - 绘图逻辑修复:
- 根据
tmin/tmax筛选目标时间区间,只绘制指定范围数据 - 使用时间索引作为X轴,解决X轴显示序号的问题
- 添加轴标签、图例、网格和标题,提升图表可读性
- 根据
- 错误防护:在
delete_oscillator中添加索引范围检查,避免越界报错
内容的提问来源于stack exchange,提问作者SmolBoi
相关产品推荐
相关产品推荐

