在 python 中绘制 3d 多边形时出现图形错误

Graphical errors plotting 3d polygons in python

我在 3D 中使用 matplotlib 绘制多边形时遇到问题。在某些情况下,似乎总是会出现某种图形错误,其中显示的多边形被其他多边形覆盖。这导致了一些非常奇怪的锁定图。但是我想不通,我在代码中哪里出错了。也许你们中的一些人以前遇到过这个问题并且已经找到了解决方案。我的示例代码如下:

from mpl_toolkits.mplot3d import Axes3D       
from mpl_toolkits.mplot3d.art3d import Poly3DCollection                                 
import matplotlib.pyplot as plt                                                         
import numpy as np                                                                      
                                                                                          
                                                                                          
z = np.zeros((10,10))                                                                   
z[5,5] = 5                                                                              
z[4,5] = 2                                                                              
z[4,4] = 2.8                                                                            
                                                                                          
nx,ny = (10,10)                                                                         
xv = np.linspace(0,9,nx)                                                                
yv = np.linspace(0,9,ny)                                                                
x,y = np.meshgrid(xv,yv)                                                                
y = np.flipud(y)                                                                        
                                                                                          
                                                                                          
fig = plt.figure()                                                                      
ax = Axes3D(fig)                                                                        
ax.set_xlim3d(np.min(np.array(x)),np.max(np.array(x)))
ax.set_ylim3d(np.min(np.array(y)),np.max(np.array(y)))                                                                     
ax.set_zlim3d(np.min(np.array(z)),np.max(np.array(z)))                                  
ax.view_init(elev=45,azim=0)                                                            
ax.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))                                           
ax.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))                                           
ax.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))                                           
ax.xaxis._axinfo["grid"]['color'] =  (1,1,1,0)                                          
ax.yaxis._axinfo["grid"]['color'] =  (1,1,1,0)                                          
ax.zaxis._axinfo["grid"]['color'] =  (1,1,1,0)                                          
ax.set_axis_off()                                                                       
                                                                                          
for d1 in range(ny-1):                                                                  
    for d2 in range(nx-1):                                                              
        xp = [x[d1,d2],x[d1+1,d2],x[d1,d2+1]]
        yp = [y[d1,d2],y[d1+1,d2],y[d1,d2+1]]                                                                                                     
        zp = [z[d1,d2],z[d1+1,d2],z[d1,d2+1]]                                           
        verts = [list(zip(xp,yp,zp))]                                                   
        ax.add_collection3d(Poly3DCollection(verts,facecolor='mediumblue',              
                                  linewidths=1,edgecolor='black'))                      
        xp = [x[d1+1,d2],x[d1+1,d2+1],x[d1,d2+1]]                                       
        yp = [y[d1+1,d2],y[d1+1,d2+1],y[d1,d2+1]]                                       
        zp = [z[d1+1,d2],z[d1+1,d2+1],z[d1,d2+1]]                                       
        verts = [list(zip(xp,yp,zp))]                                                   
        tri = ax.add_collection3d(Poly3DCollection(verts,facecolor='goldenrod',         
                                  linewidths=1,edgecolor='black'))                      
                                                                                          
plt.savefig('out.png') 

可以在此处看到显示问题的图,请查看左起第 6 列,靠近图的中间。这些错误似乎与角度有关,在其他方位角中不会发生此错误。但这不是改变方位角的解决方案,因为这样的错误可能发生在其他位置。有人知道我做错了什么以及如何做对吗?

如果旋转,您会发现深度渲染不一致是问题所在:

不幸的是,这是一个已知问题,甚至在 Matplotlib FAQ 中得到解决:

My 3D plot doesn’t look right at certain viewing angles This is probably the most commonly reported issue with mplot3d. The problem is that – from some viewing angles – a 3D object would appear in front of another object, even though it is physically behind it. This can result in plots that do not look “physically correct.”

Unfortunately, while some work is being done to reduce the occurrence of this artifact, it is currently an intractable problem, and can not be fully solved until matplotlib supports 3D graphics rendering at its core.

如果您继续阅读,他们的官方建议是暂时使用 Mayavi。如果您需要更大的灵活性,最好遵循此建议。否则,您可能不得不坚持某些可行的角度。