2017-08-24 12 views
2
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
import numpy as np 

X = np.arange(1, 4, 0.2) 
Y = np.copy(X) 
X, Y = np.meshgrid(X, Y) 

Z1 = np.copy(X) 
Z2 = 2/X 

fig = plt.figure() 
ax = fig.gca(projection='3d') 
surf1 = ax.plot_surface(X, Y, Z1, rstride=1, cstride=1, color='b') 
surf2 = ax.plot_surface(X, Y, Z2, rstride=1, cstride=1, color='r') 

plt.show() 

上記のコードを実行すると、次のようになります。注:私は、説明の目的で底面から視点を設定します。matplotlib 3Dサーフェスの透明度と色勾配?

3D Plot

つの質問:

  1. 赤い飛行機は素敵な、きれいな色のグラデーションを持っていますが、青の面は、この不規則なパターンを持っていないのはなぜ?赤のような青のパターンを作るにはどうすればいいですか?

  2. 私は、見る人の視点から見ると、どちらかの平面部分が他のものよりも前面にあるように、2つの平面を作りたいと思っています。例えば、上記の画像では、表示されている赤い平面のほとんどが表示されますが、z = sqrt(2)〜1.41の交線より上では、青い平面の後ろに隠れることになります。 Matplotlibにこれをどうすればいいのですか?

答えて

3

この例では、matplotlibのシェーディングアルゴリズムにバグがあります。シェーディング アルゴリズムは、表面の各ファセットの法線を計算し、uses the color and its normal vector to shade the facet

colset = self._shade_colors(color, normals) 

理論的に法線が、実際には、 起因数値に非常にわずかな変動があり、すべての面で同一であるが浮動小数点演算 の不明瞭な点に注意してください。これらの非常にわずかな変化は、このように完全に平面である全ての表面は、このシェーディング不具合を起こしやすい

0と1の間にあるように、この stretches the minimum and maximum shadesため normalizationにより拡大されます。

色が均一で(たとえばcolor='b')、法線がすべて同じ場合(平面の場合は )、各面のシェーディングは同じにする必要があります。正規化は陰影をゼロにする必要があります。だから飛行機の陰影は 色を全く変えてはいけません。

このように、バグを回避shade=Falseとシェーディングをオフにするには:

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

X = np.arange(1, 4, 0.2) 
Y = np.copy(X) 
X, Y = np.meshgrid(X, Y) 
Z1 = np.copy(X) 
Z2 = 2/X 

fig = plt.figure() 
ax = fig.gca(projection='3d') 

surf1 = ax.plot_surface(
    X, Y, Z1, rstride=1, cstride=1, color='b', 
    shade=False, alpha=1.0) 

surf2 = ax.plot_surface(
    X, Y, Z2, rstride=1, cstride=1, color='r', 
    shade=True, alpha=1.0) 

ax.view_init(elev=-45, azim=-30) 
plt.show() 

enter image description here


PS。あなたは正規化がゆがんで行くの正確な場所を確認したい場合は、その後、これらのprintのステートメントを配置、上記のコードでshade=Trueshade=Falseを変更、インストールのmatplotlib/colors.py

resdat = result.data 
resdat -= vmin 
print(resdat[0, :10]) 
resdat /= (vmax - vmin) 
print(resdat[0, :10]) 
result = np.ma.array(resdat, mask=result.mask, copy=False) 

その後、

を印刷し、上記のスクリプトを実行します
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 
    0.00000000e+00 0.00000000e+00 2.22044605e-16 0.00000000e+00 
    0.00000000e+00 2.22044605e-16] 
[ 0. 0. 0. 0. 0. 0. 1. 0. 0. 1.] 

resdatが均一に一定であった場合、resdatのすべての値は正規化後に0になります。代わりに、resdatの小さなエラーは1に拡大されます。これは、あなたが青い面で見ている面白い陰影につながります。

関連する問題