我想在3D中绘制一个函数,以这种方式定义
from scipy.integrate import quad
from scipy.special import jn
integrand = lambda x, r: np.exp(-x**2) * jn(0, r*x) * x
intensity = lambda r: quad(lambda x: integrand(x, r), 0, 5)
这样
intensity(1)
给了我 r = 1
的价值。
我想在3D中将其绘制为极坐标中半径的函数,因此我定义了这样的网格网格:
rho = np.linspace(0, 1.25, 50)
p = np.linspace(0, 2*np.pi, 50)
R, P = np.meshgrid(rho, p)
Z = intensity(R)
然后通过更改坐标在3D笛卡尔人中绘制它:
X, Y = R*np.cos(P), R*np.sin(P)
surf = ax.plot_surface(X, Y, Z, cmap=plt.cm.YlGnBu_r)
但是,当我将intensity
作为参数而不是单个数字而是数组时,它会抱怨
quadpack.error:提供的函数不返回有效的float。
如何将lambda函数与meshgrid结合使用?
答案 0 :(得分:1)
一旦你制作了一个meshgrid,R就不再是一个值而是一个数组。
此外,scipy.integrate.quad
返回值的元组和估计的错误。
这可能是个人品味的问题,但我喜欢将lambda仅用于匿名函数。否则,我只是感到困惑。
我的解决方案可能不是最快的,但考虑到我认为的当前参数,它已经足够好了。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.integrate import quad
from scipy.special import jn
def integrand(x, r):
return np.exp(-x**2) * jn(0, r*x) * x
def intensity(r):
output = np.zeros_like(r)
for i, ri in enumerate(r.flat):
output.flat[i] = quad(lambda x: integrand(x, ri), 0, 5)[0]
return output
rho = np.linspace(0, 1.25, 50)
p = np.linspace(0, 2*np.pi, 50)
R, P = np.meshgrid(rho, p)
Z = intensity(R)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y = R*np.cos(P), R*np.sin(P)
surf = ax.plot_surface(X, Y, Z, cmap=plt.cm.YlGnBu_r)