2017-08-24 449 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. 我想讓兩個平面,使得從觀察者的角度來看,無論平面部分是「前」其他的是可見的。例如,在上圖中,大部分紅色平面都是可見的,但在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) 

雖然理論上法線都爲一個平面是相同的,在實踐中,存在 是在適當的數值有微小變化到了浮點算術的變幻莫測的 。這些非常小的變化是由 normalization因爲這stretches the minimum and maximum shades放大到位於0和1之間

因此,這是完全平面的所有表面都容易出現這種着色缺陷。

當顏色是統一的(例如color='b')和法線都是相同的(如飛機的情況下是 ),每個方面的陰影應該是相同的。標準化應該使陰影爲零。所以對於一架飛機,陰影不應該改變顏色 。

因此,要解決這個bug,關閉遮光用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。如果你想看看那裏的正常化就會出差錯的確切位置,在上面的代碼更改shade=Falseshade=True,然後將這些print報表安裝的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所有值將正常化後爲零。相反,resdat中的微小錯誤會放大到等於1.導致您在藍色表面上看到的有趣陰影。