具有lambda函数的Meshgrid

时间:2018-02-22 11:22:39

标签: python scipy

我想在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结合使用?

1 个答案:

答案 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)