2012-03-27 12 views
1

私はfuncPower3という関数を持っています。私はMatplotLibの3Dプロット関数関数でこの関数をプロットしたいと思います。 meshgridを使ったscipy文書の例を見ました。しかし、この例では、関数が定義された関数ではなく、数学的な操作:Python matplotlib - ユーザー定義関数用のmeshgridを使用した書式設定

fig = plt.figure() 
ax = fig.gca(projection='3d') 
X = np.arange(-5, 5, 0.25) 
Y = np.arange(-5, 5, 0.25) 
X, Y = np.meshgrid(X, Y) 
R = np.sqrt(X**2 + Y**2) 
Z = np.sin(R) 
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, 
    linewidth=0, antialiased=False) 

私はこのサンプルでインスピレーションを取るが、私自身の関数シグネチャは関数meshgridのうちデータと互換性がありません。私はこのエラーを持っている:

私の関数のコードはここにある

ValueError: zero-size array to minimum.reduce without identity 

def funcPower3(PARAM): 
    inputX1 = open("power3X.txt","r") 
    inputY = open("power3Y.txt","r") 
    X1=[] 
    Y=[] 
    for line in inputX1: 
     X1.append(float(line)) 
    for line in inputY: 
     Y.append(float(line)) 
    resTmp_ = 0 
    res = 0 
    for i in range(len(X1)): 
     resTmp_ = Y[i] - (PARAM[0]*(X1[i])**float(PARAM[1])) 
     res += resTmp_**2 
    return res 

とコードこの機能を3Dプロットするためにここにある:

XMIN = 0 YMIN = 0 XMAX = 10 ymax = 1

fig = plt.figure('Power 3') 
ax = fig.gca(projection='3d') 
Z = [] 
Xpl = numpy.arange(xmin, xmax, 0.1).tolist() 
Ypl = numpy.arange(ymin, ymax, 0.01).tolist() 
Xpl, Ypl = numpy.meshgrid(Xpl, Ypl) 
Z=[] 
for i in range(len(Xpl[0])): 
    for j in range(len(Xpl)): 
     Z.append(funcPower3([Xpl[j][i],Ypl[j][i]])) 
surf=ax.plot_surface(Xpl, Ypl, Z, rstride=8, cstride=8, alpha=0.3,cmap=cm.jet) 
ax.set_xlabel('X Label') 
ax.set_ylabel('Y Label') 
plt.show() 

助言を求めています。 ))

答えて

4

plot_surfacedocumentationからの引用:

X, Y, Z : Data values as 2D arrays

しかし、あなたのZが1次元です。 XYの値に一致するように変更する必要があります。これはうまくいくはずです:

Xpl = numpy.arange(xmin, xmax, 0.1).tolist() 
Ypl = numpy.arange(ymin, ymax, 0.01).tolist() 
Xpl, Ypl = numpy.meshgrid(Xpl, Ypl) 

Z=[] 
for j in range(len(Xpl)): 
    for i in range(len(Xpl[0])): 
     # your loop order was backwards 
     Z.append(funcPower3([Xpl[j][i],Ypl[j][i]])) 

# reshape Z 
Z = numpy.array(Z).reshape(Xpl.shape) 

fig = plt.figure('Power 3') 
ax = fig.gca(projection='3d') 
surf=ax.plot_surface(Xpl, Ypl, Z, rstride=8, cstride=8, alpha=0.3,cmap=cm.jet) 
ax.set_xlabel('X Label') 
ax.set_ylabel('Y Label') 
plt.show() 

しかし、コードにはいくつかの欠陥があります。まず、funcPower3関数を見て、関数呼び出しごとに2つのファイルを何度も読み込んでいます。これはあまりにも無駄です。代わりにそれらのパラメータを一度読んで、パラメータとして関数に与えます。この関数は、(とPEP8命名規則に従うことを試してください)ビットを単純化することができます。

def func_power_3(param, x1, y): 
    p1, p2 = param 
    res = sum(y_i - (p1*x1_i)**p2 for x1_i, y_i in zip(x1, y)) 
    return res 

、残りは

with open("power3X.txt","r") as infile: 
    x1 = [float(line) for line in infile] 

with open("power3Y.txt","r") as infile: 
    y = [float(line) for line in infile] 

xpl = numpy.arange(xmin, xmax, 0.1) # no need for .tolist() 
ypl = numpy.arange(ymin, ymax, 0.01) # meshgrid can work with numpy.array's 
xpl, ypl = numpy.meshgrid(xpl, ypl) 

# we can form z with list comprehension 
z = [[func_power_3([p1,p2], x1, y) for p1, p2 in zip(p1row, p2row)] 
            for p1row, p2row in zip(xpl, ypl)] 

fig = plt.figure('Power 3') 
ax = fig.gca(projection='3d') 
surf=ax.plot_surface(xpl, ypl, z, rstride=8, cstride=8, alpha=0.3,cmap=cm.jet) 
ax.set_xlabel('X Label') 
ax.set_ylabel('Y Label') 
plt.show() 
+0

になりますこれは非常に有望に見えるとコードは、超明確です。私はこのエラーで少し問題があります: "open(open(" power3X.txt "、" r "))をinfileとして: TypeError:Unicodeに強制します:文字列またはバッファが必要です" – octoback

+0

@dlib:oops too非常に '開いた')。今すぐ修正。 – Avaris

+0

open( "power3Y.txt"、 "r")をinfileとして修正する: y = [infileの行のためのfloat]、素晴らしい動作します! – octoback

関連する問題