2017-07-02 30 views
1

我不知道我怎麼會在下面的代碼Streamplot在Python錯誤

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} $的流圖,其中$ u _ {\ theta} = \ frac {g} {\ omega a} \ frac {d} {d \ theta} \ left(P^n_l \ left(cos \ theta \ right)\ right)sin \ left(n \ phi \ωmega\ right)$ and $ u _ {\ phi} = \壓裂{GN} {\歐米加罪過\ THETA} p^N_L \左(COS \ THETA \右)COS \左(N \ PHI-\歐米加噸\右)$

編輯:

這是我現有的代碼:

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() 

當前問題似乎與中的衍生函數,在繪製第一個繪圖並繪製到第二個繪圖後出現錯誤ValueError: math domain error

回答

1

而Python 3允許您使用希臘字符/變量名,我可以向你保證,大多數程序員會發現你的代碼不可讀的,這將是一個惡夢爲他人維護/開發代碼與φ千瘡百孔和θ。其次,你的代碼很快會拋出一個RuntimeWarning有關除零的劃分,你應該很確定地追查和修復。

至於你的問題,這個問題是雙重的。第一個問題是,您輸入的尺寸不調用匹配streamline

>>> print(φ.shape, θ.shape, uφ.shape, uθ.shape) 
(256,) (128,) (256, 128) (256, 128) 

訣竅是,很多matplotlib積函數預計其二維數組尺寸的換位,密切相關的numpy.meshgrid奇怪的定義:

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

可能是由於這個原因,definition of streamplot is as follows

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. 

請注意關於尺寸的最後一點。所有你需要做的就是交換x/y,或者調整角度;您需要檢查其中哪一個會導致應用程序中更有意義的情節。

現在,如果你解決這個問題,會發生以下情況:

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

現在,這是腥。所有輸入類型都應該是數字......對吧?嗯,是的,但它們不是:

>>> print(φ.dtype, θ.dtype, uφ.dtype, uθ.dtype) 
float64 float64 object float64 

那是什麼第三object -typed陣列呢?

>>> 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'> 

作爲@Jelmes noted in a comment。上述類型的是使用sympy構建的直接後果。如果在構造結果數組之前將這些sympy浮點數轉換爲python或numpy浮點數,則dtype問題應該消失。另一個問題是,剩餘的無窮大(1/sin(X)中0的除法結果)將優於streamplot處理。

+1

儘管'np.sin(X)'在0和$ \ pi $處的劃分不是很好,但在我看來'dtype'與函數'Assoc_Legendre'和'Der_Assoc_Legendre'有差別。我不太清楚如何修復這個 – Jelmes

+0

@Jelmes你是對的,我不知何故錯過了只有有問題的人才用sympy來計算。因此改爲'append(float(assoc_legendre(...)))',但是你仍然會有無窮無盡(我們將會看到'streamplot'如何處理這些)。 –

+0

PS謝謝;) –