2017-06-18 7 views
2

意味のない負の値を持つ3次元関数をプロットする必要があります(プロット内に表示しないでください)。Matplotlibは3Dプロットで負の値を無視します

xs = np.linspace(0, 3600, 1000) 
ys = np.linspace(0, 3600, 1000) 
zs = np.empty(shape=(1000, 1000)) 
for ix, x in enumerate(xs): 
    for iy, y in enumerate(ys): 
     zs[ix][iy] = constraint_function(x, y) 
xs, ys = np.meshgrid(xs, ys) 

機能は主に正方形の[0, 3600]x[0, 3600]に有効な値を持っている:私は、関数に次のように計算しています

def constraint_function(x, y): 
    return min(
     (1800 - 0.3 * x - 0.5 * y)/0.4, 
     (500 - 0.1 * x - 0.08 * y)/0.12, 
     (200 - 0.06 * x - 0.04 * y)/0.05 
    ) 

:のようにプロットすることがある機能です。私が持っていた最初のアプローチは、私のニーズに合うように軸の範囲を設定している次のプロットになり

fig = plt.figure() 

ax = fig.add_subplot(111, projection='3d') 
ax.azim = 20 
ax.set_xlim(0, 3500) 
ax.set_ylim(0, 3500) 
ax.set_zlim(0, 4500) 
ax.plot_surface(xs, ys, zs) 

plt.show() 

は:

enter image description here はそれだけで制限を無視し、とにかくそれをプロットしました。それは、のこぎりのように私を残し

plt.cm.jet.set_bad(alpha=0.0) 
ax.azim = 20 
ax.set_xlim(0, 3500) 
ax.set_ylim(0, 3500) 
ax.set_zlim(0, 4500) 

ax.plot_surface(xs, ys, zs) 

plt.show() 

enter image description here

def constraint_function(x, y): 
    temp = min(
     (1800 - 0.3 * x - 0.5 * y)/0.4, 
     (500 - 0.1 * x - 0.08 * y)/0.12, 
     (200 - 0.06 * x - 0.04 * y)/0.05 
    ) 
    return temp if temp >= 0 else np.nan 

とゼロに無効な値のアルファを設定する:ように、第2のアプローチは、なるように機能を変更np.nanとして負の値を定義しました。私が持たないこともある国境です。プロットがマイナスになっているときに、これらのエッジを取り除き、滑らかな線を得る方法はありますか?

答えて

1

まず、z値の配列の軸を逆にします。 zs[iy][ix]ではなく、zs[ix][iy]である必要があります。このため、あなたのプロットは左右に反転されます。

第2に、Pythonで反復処理することによってz配列を構築する方がはるかに遅くなります。あなたの代わりにそうように、numpyのために委任する必要があります。

import numpy as np 
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 

# create axis sample 
xs = np.linspace(0, 3600, 1000) 
ys = np.linspace(0, 3600, 1000) 

# create mesh samples 
xxs, yys = np.meshgrid(xs, ys) 

# create data 
zzs = np.min([ 
    ((1800 - 0.30 * xxs - 0.50 * yys)/0.40), 
    ((500 - 0.10 * xxs - 0.08 * yys)/0.12), 
    ((200 - 0.06 * xxs - 0.04 * yys)/0.05) 
], axis=0) 

# clip data which is below 0.0 
zzs[zzs < 0.] = np.NaN 

numpyのベクトル化操作が何倍も高速です。

第3に、サンプリング解像度が低すぎることを除いて、コードに特に問題はありません。

fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 
ax.azim = 20 
ax.set_xlim(0, 3500) 
ax.set_ylim(0, 3500) 
ax.set_zlim(0, 4500) 
ax.plot_surface(xxs, yys, zzs, rcount=200, ccount=200) 

plt.show() 

enter image description here

0

技術を生成し、それを高く設定、あなたはzick-ザックパターンを引き起こす格子、点があること、などにシフトしているように、グリッドを歪曲することができます彼らはラインに横たわっています。

これを以下に示します。

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 

x=np.linspace(-5,5,6) 
X,Y = np.meshgrid(x,x) 
Z = X+Y 

X[Z==-2] = X[Z==-2]+1 
Y[Z==-2] = Y[Z==-2]+1 
Z[Z==-2] = 0 
Z[Z<0] = np.nan 

fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 

ax.set_zlim(0, 12) 
ax.plot_surface(X, Y, Z) 

plt.show() 

enter image description here

問題は今、任意の表面についてこの手法を一般化することであろう。確かに可能ですが、ちょっとした作業が必要です。

関連する問題