如何替换Sympy计算中的变量以适配Matplotlib和Numpy绘图
解决Sympy符号表达式转Numpy数组计算并绘制3D线框图的问题
问题核心
你当前的代码中,s是Sympy生成的符号表达式,直接在u(x,t)中返回它时,无法自动将Numpy生成的数组代入计算——因为Sympy的符号变量和Numpy数组属于不同类型,不能直接进行数值运算;同时你还犯了变量名冲突的错误:原本定义的Sympy符号x、t被后续的Numpy数组覆盖,导致符号表达式无法正确关联到新的数值输入。
解决方案
使用Sympy的lambdify函数将符号表达式转换为可处理Numpy数组的数值计算函数,同时避免变量名冲突。
修改后的完整代码
import numpy as np import sympy as sm from sympy import * from mpl_toolkits import mplot3d import matplotlib.pyplot as plt # 1. 符号计算部分:保留独立的符号变量 x_sym = sm.symbols("x") t_sym = sm.symbols("t") n = sm.symbols("n", integer=True) L = 20 f1 = (2/L)*x_sym*sin(n*np.pi*x_sym/20) f2 = (2/L)*(20-x_sym)*sin(n*np.pi*x_sym/20) fint1 = sm.integrate(f1,(x_sym,0,10)) fint2 = sm.integrate(f2,(x_sym,10,20)) D = 0.475 g = (fint1+fint2)*sin(n*np.pi*x_sym/20)*exp(-(n**2)*(np.pi**2)*D*t_sym/400).nsimplify() # 求和得到符号表达式s(跳过n=0的无效项) s = 0 for c in range(1, 10): s += g.subs({n:c}) print('The function u(x,t) : ') sm.pretty_print(s) # 2. 转换符号表达式为可处理Numpy数组的函数 u = sm.lambdify((x_sym, t_sym), s, modules='numpy') # 3. 生成数值网格:用不同变量名避免冲突 x_vals = np.linspace(0, 20, 50) t_vals = np.linspace(0, 10, 50) X, T = np.meshgrid(x_vals, t_vals) # 4. 计算Z值 Z = u(X, T) print('\nu(x,t)的数值结果:') print(Z) # 5. 绘制3D线框图 fig = plt.figure() ax = plt.axes(projection='3d') ax.plot_wireframe(X, T, Z, cmap='viridis', edgecolor='green') ax.set_xlabel('x') ax.set_ylabel('t') ax.set_zlabel('u(x,t)') ax.set_title('Wireframe') plt.show()
关键修改点
- 变量名分离:将Sympy符号变量命名为
x_sym、t_sym,Numpy数值数组用x_vals、t_vals,避免覆盖冲突。 - 使用
lambdify:把符号表达式s转换成能接受Numpy数组的函数u,指定modules='numpy'确保用Numpy的数学函数进行数值计算。 - 优化求和循环:跳过
c=0的项(代入n=0时整个项为0,无意义),从c=1开始循环。
修改后即可正确计算Z数组并绘制3D线框图。
内容的提问来源于stack exchange,提问作者Freya the Goddess
相关产品推荐
相关产品推荐

