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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:31:05