Python错误中的Streamplot

时间:2017-07-02 19:28:12

标签: python python-3.x numpy matplotlib

我想知道如何修复以下代码中的错误

import numpy as np
import matplotlib.pyplot as plt
from sympy.functions.special.polynomials import assoc_legendre
from scipy.misc import factorial, derivative
import sympy as sym

def main():
    t = 36000
    a=637000000
    H=200
    g=9.81
    x = sym.symbols('x')

    for l in range(1, 6):
        ω=np.sqrt(g*H*l*(l+1))/a

        for n in range(l+1):
            nθ, nφ = 128, 256
            θ, φ = np.linspace(0, np.pi, nθ), np.linspace(0, 2*np.pi, nφ)
            legfun_sym = sym.functions.special.polynomials.assoc_legendre(l, n, x)
            legfun_num = sym.lambdify(x,legfun_sym)

            X, Y = np.meshgrid(θ, φ)

            uθ = (g/(a*ω))*Der_Assoc_Legendre(legfun_num, l, n, X)*np.sin(n*Y-ω*t)
            uφ = (g/(a*ω*np.sin(X)))*Assoc_Legendre(l, n, X)*np.cos(n*Y-ω*t)
            #speed = np.sqrt(uθ**2 + uφ**2)

            fig0, ax = plt.subplots()
            strm = ax.streamplot(φ, θ, uφ, uθ, linewidth=2, cmap=plt.cm.autumn)
            fig0.colorbar(strm.lines)
            plt.show()

def Assoc_Legendre(m, n, X):
    L=[]
    for i in X:
        k=[]
        for j in i:
            k.append(assoc_legendre(m, n, np.cos(j)))
        L.append(k)
    return np.array(L)

def Der_Assoc_Legendre(legfun_num, m, n, X):
    L=[]
    for i in X:
        k=[]
        for j in i:
            k.append(derivative(legfun_num, j, dx=1e-7))
        L.append(k)
    return np.array(L)

if __name__=='__main__':
    main()

关于'u' and 'v' must be of shape 'Grid(x,y)'行,会出现错误消息strm = ax.streamplot(φ, θ, uφ, uθ, linewidth=2, cmap=plt.cm.autumn)。我该如何解决这个问题?

作为参考,我正在尝试做一个$ u _ {\ theta} $和$ u _ {\ phi} $的streamplot,其中$ u _ {\ theta} = \ frac {g} {\ omega a} \ frac {d} {d \ theta} \ left(P ^ n_l \ left(cos \ theta \ right)\ right)sin \ left(n \ phi- \ omega t \ right)$和$ u _ {\ phi} = \ frac {gn} {\ omega a sin \ theta} P ^ n_l \ left(cos \ theta \ right)cos \ left(n \ phi- \ omega t \ right)$

编辑:

这是我目前的代码:

import numpy as np
import matplotlib.pyplot as plt
from sympy.functions.special.polynomials import assoc_legendre
from scipy.misc import factorial, derivative
import sympy as sym

def main():
    t = 36000
    a=637000000
    H=200
    g=9.81
    x = sym.symbols('x')
    X, Y = np.mgrid[0.01:np.pi-0.01:100j,0:2*np.pi:100j]

    for l in range(1, 6):
        ω=np.sqrt(g*H*l*(l+1))/a

        for n in range(l+1):
            #nθ, nφ = 128, 256
            #θ, φ = np.linspace(0.001, np.pi-0.001, nθ), np.linspace(0, 2*np.pi, nφ)
            legfun_sym = sym.functions.special.polynomials.assoc_legendre(l, n, x)
            legfun_num = sym.lambdify(x, legfun_sym)
            uθ = (g/(a*ω*np.sin(X)))*Der_Assoc_Legendre(legfun_num, l, n, X)*np.sin(n*Y-ω*t)
            uφ = (g/(a*ω))*Assoc_Legendre(l, n, X)*np.cos(n*Y-ω*t)
            #speed = np.sqrt(uθ**2 + uφ**2)
            fig0, ax = plt.subplots()
            strm = ax.streamplot(Y, X, uθ,uφ, linewidth=0.5, cmap=plt.cm.autumn)
            #fig0.colorbar(strm.lines)
            plt.show()
            print("next")

def Assoc_Legendre(m, n, X):
    L=[]
    for i in X:
        k=[]
        for j in i:
            k.append(assoc_legendre(m, n, np.cos(j)))
        L.append(k)
    return np.float64(np.array(L))

def Der_Assoc_Legendre(legfun_num, m, n, X):
    L=[]
    for i in X:
        k=[]
        for j in i:
            k.append(derivative(legfun_num, j, dx=0.001))
        L.append(k)
    return np.float64(np.array(L))

if __name__=='__main__':
    main()

当前问题似乎与Der_Assoc_Legendre中的派生函数有关,在绘制第一个绘图并绘制到第二个绘图之后会出现错误ValueError: math domain error

1 个答案:

答案 0 :(得分:1)

虽然python 3允许你在变量名中使用希腊字符,但我可以向你保证,大多数程序员会发现你的代码不可读,对于其他人而言,维护/开发充满{{1}的代码将是一场噩梦。 }和φ

其次,你的代码会快速抛出一个θ关于除零的问题,你应该最好地追踪并安全地修复。

至于你的问题,问题是双重的。第一个问题是您的输入维度在调用RuntimeWarning时不匹配:

streamline

诀窍在于很多>>> print(φ.shape, θ.shape, uφ.shape, uθ.shape) (256,) (128,) (256, 128) (256, 128) 绘图函数需要转换其2d数组维度,与matplotlib的奇怪定义密切相关:

numpy.meshgrid

可能由于这个原因,definition of streamplot is as follows

>>> i,j = np.meshgrid(range(3),range(4))
>>> print(i.shape)
(4, 3)

请注意有关尺寸的最后一点。你需要做的就是交换x / y,或者转换角度;你需要检查哪一个会在你的应用程序中产生更有意义的情节。

现在,如果您解决此问题,则会发生以下情况:

  

TypeError:ufunc' isfinite'不支持输入类型,并且根据投射规则无法安全地将输入强制转换为任何支持的类型'''

现在这很可疑。所有输入类型都应该是数字......对吧?嗯,是的,但他们不是:

 Axes.streamplot(ax, *args, **kwargs)

    Draws streamlines of a vector flow.

    x, y : 1d arrays
        an evenly spaced grid.
    u, v : 2d arrays
        x and y-velocities. Number of rows should match length of y, and the number of columns should match x.

关于第三个>>> print(φ.dtype, θ.dtype, uφ.dtype, uθ.dtype) float64 float64 object float64 类型数组的内容是什么?

object

作为@Jelmes noted in a comment。上述>>> print(uφ[0,0],uθ[0,0]) +inf -0.00055441014491 >>> print(type(uφ[0,0]),type(uθ[0,0])) <class 'sympy.core.numbers.Float'> <class 'numpy.float64'> 类型是使用sympy进行构造的直接后果。如果在构造结果数组之前将这些sympy浮点数转换为python或numpy浮点数,则问题应该消失。另一个问题是,dtype是否会优雅地处理剩余的无穷大(1/sin(X)中除以0的结果)。