2016-03-16 80 views
1

我是python的新手,嘗試用3d繪製分段函數。我試圖在z軸上繪製下面的'mainformula'函數,因爲它隨着x和y的變化而變化,範圍從0到10,常數= 1。但我似乎無法弄清楚這裏的繪圖方法。在3D中繪製分段函數

from sympy import * 
from mpl_toolkits.mplot3d import Axes3D 
from matplotlib import cm 
from matplotlib.ticker import LinearLocator, FormatStrFormatter 
import matplotlib.pyplot as plt 
import numpy as np 

def mainformula(x,y,constant): 
    return Piecewise((subformula1(x,y,constant), y >= 0 and y < 3),(subformula2(x,y,constant),y>=3 and y <= 10)) 

def subformula1(x,y,constant): 
    return x + y + constant 

def subformula2(x,y,constant):  
    return x - y - constant 

fig = plt.figure() 
ax = fig.gca(projection='3d') 
X = np.arange(0, 10, 0.25) 
Y = np.arange(0, 10, 0.25) 
constant = 1 
X, Y = np.meshgrid(X, Y) 
Z = mainformula(X,Y,constant) 
surf = ax.plot_surface(X, Y, Z) 
plt.show() 

當我運行該代碼我得到的錯誤是:「ValueError異常:陣列的具有多於一個元素的真值是不明確的使用a.any()或a.all()」。

回答

1

您正在處理數組,因此它永遠不會在布爾上下文中使用array > 3(例如使用and),這會始終給您提供您收到的錯誤。但你總是可以定義你的條件布爾口罩和適當的元素操作配方:

def mainformula(x,y,constant): 
    z = np.zeros_like(x) 
    # Condition 1 indexes all elements where subformula 1 is valid 
    condition1 = np.logical_and(y >= 0, y < 3) 
    # condition1 = (y >= 0) & (y < 3) # is another way of writing it 
    z[condition1] = x[condition1] + y[condition1] + constant 
    # now do it in the range where subformula 2 is valid 
    condition2 = np.logical_and(y >= 3, y <= 10) 
    # condition1 = (y >= 3) & (y <= 10) # is another way of writing it 
    z[condition2] = x[condition2] - y[condition2] - constant 

    return z 

這不使用sympy.Piecewise但工作正常的時候只想要繪製。如果你想單獨的功能,而不是做這一切的主要公式中你需要改變它一下:

z[condition1] = subformula1(x[condition1], y[condition1], constant) 

condition2類似。

+0

非常感謝。這符合我期待的目標。我能爲此添加一些複雜性嗎? 有沒有一種方法可以將「condition1 = np.logical_and(y> = 0,y <3)」更改爲具有其他條件: condition1 = np.logical_and(y> = 0,y <3 )和np.logical_and(subformula1(x,y,constant)> = 0) – racemic

+0

當然,您也可以使用'&'代替'np.logical_and'並將其表述爲'condition1 =(y> = 0)& (y <3)&(subformula1(x,y,constant)> = 0)',但這會排除設置最後一個'z'中的某些元素。例如,如果'0 MSeifert

+0

非常感謝,這就是訣竅。最後一件事。有沒有這樣的事情np.logical(沒有和所以我不必提供2個參數)?所以我想要這樣的: np.logical_and(y> = 0,y <3)到np.logical(y <3)? – racemic

0

問題是您正在嘗試將邏輯斷言轉換爲沒有直接邏輯斷言的數組。這是很難的Python斷言這是什麼:

y >= 0 and y < 3 

所以你必須要有所更改您的代碼到的東西就可以明白:

def mainformula(x,y,constant): 
     y2 = y[y>=0] 
     y2 = y2[y2<3] 
     y3 = y[y>=3] 
     y3 = y2[y2<=10] 
     return Piecewise((subformula1(x,y,constant), y2),(subformula2(x,y,constant),y3)) 

問題是分段函數也似乎沒有接受一些數組到你有的參數中。您必須重新考慮您的問題,也許可以通過構建Piecewise函數的循環來啓動每個元素。