简体   繁体   English

Matplotlib plot_surface transparency artefact

[英]Matplotlib plot_surface transparency artefact

I'm trying to plot a surface in 3D from a set of data which specifies the z-values. 我试图从一组指定z值的数据中绘制3D表面。 I get some weird transparency artefact though, where I can see through the surface, even though I set alpha=1.0. 虽然我设置了alpha = 1.0,但我得到了一些奇怪的透明效果,我可以在表面看到。

The artefact is present both when plotting and when saved to file (both as png and pdf): 在绘图时和保存到文件时(包括png和pdf)都会出现人工制品: 在此输入图像描述

I have tried changing the line width, and changing the number of strides from 1 to 10 (in the latter case, the surface is not visible though due to too rough resolution). 我已经尝试改变线宽,并将步幅数从1改为10(在后一种情况下,由于分辨率太粗糙,表面不可见)。

Q: How can I get rid of this transparency? 问:我怎样才能摆脱这种透明度?

Here is my code: 这是我的代码:

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()

Here is another picture of my actual data where it is easier to see the artefact: 这是我的实际数据的另一张图片,它更容易看到人工制品: 在此输入图像描述

Matplotlib is not a "real" 3D engine. Matplotlib不是一个“真正的”3D引擎。 This is a very well known problem and once in a while a similar question to yours appears appears (see this and this ). 这是一个众所周知的问题,偶尔出现一个与你类似的问题(见本节 )。 The problem is that the same artefact can originate problems that seem to be different. 问题是同样的人工制品可能会产生似乎不同的问题。 I believe such is the case for you. 我相信你就是这种情况。

Before going on with my recommendations let me just quote this information from the maplotlib website : 在继续我的推荐之前,让我引用maplotlib网站上的这些信息

My 3D plot doesn't look right at certain viewing angles 我的3D绘图在某些视角看起来并不正确

This is probably the most commonly reported issue with mplot3d. 这可能是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. 问题在于 - 从某些视角 - 一个3D物体会出现在另一个物体的前面,即使它在物体后面。 This can result in plots that do not look “physically correct.” 这可能会导致图形看起来“物理上不正确”。

Unfortunately, while some work is being done to reduce the occurance of this artifact, it is currently an intractable problem, and can not be fully solved until matplotlib supports 3D graphics rendering at its core . 不幸的是,虽然正在做一些工作来减少这个工件的出现,但它目前是一个棘手的问题,并且在matplotlib支持其 核心的 3D图形渲染之前 无法 完全解决

The problem occurs due to the reduction of 3D data down to 2D + z-order scalar. 由于3D数据减少到2D + z阶标量,会出现问题。 A single value represents the 3rd dimension for all parts of 3D objects in a collection. 单个值表示集合中3D对象的所有部分的第三维。 Therefore, when the bounding boxes of two collections intersect, it becomes possible for this artifact to occur. 因此,当两个集合的边界框相交时,可能会发生此工件。 Furthermore, the intersection of two 3D objects (such as polygons or patches) can not be rendered properly in matplotlib's 2D rendering engine. 此外,matplotlib的2D渲染引擎无法正确渲染两个3D对象(如多边形或面片)的交集。

This problem will likely not be solved until OpenGL support is added to all of the backends (patches are greatly welcomed). 在将OpenGL支持添加到所有后端之前,这个问题可能无法解决 (非常欢迎补丁)。 Until then, if you need complex 3D scenes, we recommend using MayaVi . 在此之前,如果您需要复杂的3D场景,我们建议您使用MayaVi

It seems that Mayavi has finally moved on to Python 3 , so its certainly a possibility. 似乎Mayavi终于转向了Python 3 ,所以它肯定有可能。 If you want to stick with matplotlib for this kind of plot my advice is that you work with rstride and cstride values to see which ones produce a plot satisfactory to you. 如果你想坚持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
                      )

Other possibility is to try to see if other kinds of 3D plots do better. 其他可能性是试图看看其他类型的3D图表是否做得更好。 Check plot_trisurf , contour or contourf . 检查plot_trisurfcontourcontourf I know its not ideal but in the past I also managed to circumvent other type of artefacts using 3D polygons . 我知道它并不理想,但在过去,我还设法绕过使用3D多边形的其他类型的人工制品

Sorry for not having a more satisfactory answer. 很抱歉没有更满意的答案。 Perhaps other SO users have better solutions for this. 也许其他SO用户有更好的解决方案。 Best of luck. 祝你好运。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM