numpy Matplotlib plot_surface透明度伪影

ruyhziif  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(143)

我试图从一组指定z值的数据中绘制3D表面。我得到了一些奇怪的透明伪影,即使我设置alpha=1.0,我也可以看到表面。
在绘图和保存到文件(png和pdf格式)时,都会出现伪影:

我试过改变线宽,并将步幅从1改为10(在后一种情况下,由于分辨率太粗糙,表面不可见)。

Q:我如何才能摆脱这种透明度?

下面是我的代码:

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

y_label = r'x'
x_label = r'y'
z_label = r'z'

x_scale = 2.0*np.pi
y_scale = 2.0*np.pi

y_numPoints = 250
x_numPoints = 250

def quasiCrystal(x, y):
    z = 0
    for i in range(0,5):
        z += np.sin(x * np.cos(float(i)*np.pi/5.0) +
                    y * np.sin(float(i)*np.pi/5.0))
    return z

x = np.linspace(-x_scale, x_scale, x_numPoints)
y = np.linspace(-y_scale, y_scale, y_numPoints)
X,Y = np.meshgrid(x,y)

Z = quasiCrystal(X, Y)

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

surf = ax.plot_surface( X, Y, Z,
                        rstride=5, cstride=5,
                        cmap='seismic',
                        alpha=1,
                        linewidth=0,
                        antialiased=True,
                        vmin=np.min(Z),
                        vmax=np.max(Z)
                      )

ax.set_zlim3d(np.min(Z), np.max(Z))

f.colorbar(surf, label=z_label)

ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
ax.set_zlabel(z_label)

plt.show()

这是我的实际数据的另一张图片,更容易看到人工制品:

ccrfmcuu

ccrfmcuu1#

Matplotlib不是一个“真实的”3D引擎。这是一个众所周知的问题,偶尔会出现与您类似的问题(参见此和此)。问题是,同样的人工制品可能会引发看似不同的问题。我相信你也是如此。
在继续我的建议之前,让我先quote this information from the matplotlib website

我的3D图在某些视角下看起来不正确

这可能是mplot3d最常报告的问题。问题是,从某些视角来看,一个3D物体会出现在另一个物体的前面,即使它实际上在它的后面。这可能会导致图看起来“物理上不正确”。
不幸的是,虽然已经做了一些工作来减少这个工件的发生,但它目前是一个棘手的问题,并且直到matplotlib在其 * 核心支持3D图形渲染才能完全解决。
该问题是由于将3D数据减少到2D + z阶标量而发生的。单个值表示集合中3D对象的所有部分的第三维。因此,当两个集合的边界框相交时,就有可能出现这种伪影。此外,两个3D对象(如多边形或补丁)的交集不能在matplotlib的2D渲染引擎中正确渲染。

这个问题可能不会得到解决,直到OpenGL支持添加到所有的后端(补丁非常欢迎)。在此之前,如果您需要复杂的3D场景,我们建议您使用MayaVi

It seems that Mayavi has finally moved on to Python 3,所以这是一种可能性。如果你想坚持使用matplotlib来绘制这种图,我的建议是,你应该使用rstride和cstride值,看看哪些值能生成令你满意的图。

surf = ax.plot_surface( X, Y, Z,
                        rstride=5, cstride=5,
                        cmap='jet',
                        alpha=1,
                        linewidth=0,
                        antialiased=True,
                        vmin=0,
                        rstride=10,
                        cstride=10,
                        vmax=z_scale
                      )

另一种可能性是尝试看看其他类型的3D图是否做得更好。检查plot_trisurf、contour或contourf。我知道这并不理想,但在过去,我也设法绕过其他类型的文物使用3D多边形。
抱歉,我没有更满意的答案。也许其他用户对此有更好的解决方案。祝你好运

bakd9h0s

bakd9h0s2#

我遇到了一些类似的问题,发现它们是抗锯齿工件,可以通过在plot_surface中设置antialiased=False来修复。

相关问题