如何用Python绘制微分方程?解决ValueError与下标报错问题
解决微分方程解绘图时的维度不匹配与下标错误问题
我来帮你排查下这两个问题,其实核心原因是你没处理好sympy返回的解的类型,咱们一步步拆解解决:
先分析报错原因
第一个报错:ValueError: x and y must have same first dimension, but have shapes (360,) and (1,)
你用sympy.dsolve()得到的结果q是一个Equality对象(也就是类似i(t) = 表达式的等式),不是直接的数值数组。当你代入常数得到final后,它依然是一个等式,不是可以直接绘图的数值序列。所以plt.plot(t, final)时,final被当成单个元素,维度是(1,),和t的(360,)不匹配,就报错了。
第二个报错:Equality object is not subscriptable
因为final是Equality对象(等式),这类对象不支持下标操作(比如[:1]),所以你尝试切片时会触发这个错误。
修正方案与完整代码
我们需要把sympy的符号表达式转换成numpy可计算的函数,再生成对应t数组的数值序列,具体步骤如下:
- 从微分方程的解中提取出
i(t)的表达式(也就是等式的右侧部分) - 用
sympy.lambdify把符号表达式转换成可以接收numpy数组的函数 - 用这个函数计算所有t对应的i值,再绘图
修正后的完整代码:
import numpy as np import matplotlib.pyplot as plt from sympy.abc import * import sympy as sy L = float(input('L:')) R = float(input('R:')) v = 220 * sy.sqrt(2) i = sy.Function('i') # 求解微分方程,得到等式形式的解 sol = sy.dsolve(sy.Eq(sy.Derivative(i(t)*L, t) + i(t)*R, v*sy.sin(t)), i(t)).evalf() # 提取解的右侧(即i(t)的表达式) i_expr = sol.rhs # 求解初始条件对应的常数(t=0时i(t)=0) constant = sy.solve(i_expr.subs(t, 0), dict=True) # 代入常数,得到完整的i(t)表达式 i_expr_with_const = i_expr.subs(constant[0]) # 把符号表达式转换成numpy可计算的函数 i_func = sy.lambdify(t, i_expr_with_const, 'numpy') # 生成t数组 t = np.linspace(0, 360, 360) # 计算每个t对应的i值 y = i_func(t) # 绘图 plt.plot(t, y) plt.show()
关键修改点说明
- 用
sol.rhs提取等式右侧的i(t)表达式,避免直接操作Equality对象 - 使用
sy.lambdify将符号表达式转为numpy兼容的函数,这样传入t数组就能批量计算出对应的y值,保证维度和t一致 - 修正了初始条件的代入逻辑:原代码中
q.subs(i(t),0)是错误的,应该是代入t=0时i(t)=0,所以改成i_expr.subs(t, 0)来求解常数
内容的提问来源于stack exchange,提问作者Deniz Güler
相关产品推荐
相关产品推荐

