python - Matplotlib 3Dplot 尺寸不相等时出现额外线条

标签 python matplotlib

考虑这个 MWE:

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

n = 15
m = 12

x = np.linspace(-5, 5, n)
y = np.linspace(-5, 5, m)

Z = np.zeros((m, n))
for i in xrange(m):
    for j in xrange(n):
        Z[i, j] = x[j]**2 + y[i]**2


### Plot surface ###
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y = np.meshgrid(x, y)
ax.plot_surface(X, Y, Z)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('Z')
plt.show()

特别注意,尺寸nm 不相等。生成的图有一些奇怪的线条,以及奇怪的颜色:plot

这是怎么回事?我该如何防止这种情况发生?

最佳答案

与 2D 不同,matplotlib 中的 3D 绘图有很多 shortcomings 。让我引用 matplotlib FAQ 中的答案之一:

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 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.

The problem occurs due to the reduction of 3D data down to 2D + z-order scalar. A single value represents the 3rd dimension for all parts of 3D objects in a collection. 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.

This problem will likely not be solved until OpenGL support is added to all of the backends (patches are greatly welcomed). Until then, if you need complex 3D scenes, we recommend using MayaVi.

对于您的特定问题(请注意,我认为这与每个方向的不同尺寸没有任何关系),我建议您增加表面形状(即使是人为的)并调整步数直到你得到满意的东西:

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

n = 150
m = 120

x = np.linspace(-5, 5, n)
y = np.linspace(-5, 5, m)

Z = np.zeros((m, n))
for i in range(m):
    for j in range(n):
        Z[i, j] = x[j]**2 + y[i]**2


### Plot surface ###
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y = np.meshgrid(x, y)
ax.plot_surface(X, Y, Z,rstride=1, cstride=1)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('Z')
plt.show()

,结果如下:

Matplotlib surface with rstrides and cstrides == 10

上面的示例将 rstride 和 cstrides 的值设置为 10。如果将其增加太多(假设为 80),问题就会变得明显:

Matplotlib surface with rstrides and cstrides == 80

其他选项是让您遵循 matplotlib FAQ 本身的建议并检查 Mayavi 。但请注意,mayavi 仍然不支持 Python 3。就个人而言,如果您需要快速使用的东西,我会推荐 PyQtGraph .

关于python - Matplotlib 3Dplot 尺寸不相等时出现额外线条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37488379/

相关文章:

不同 DataFrame 并排的 Pandas 箱线图

python-2.7 - matplotlib具有奇数个子图

python - django rest框架中日期的国际化?

java - 模拟器框架

python - IEP 中 Python 的乘法表?

python - 试图绘制二元正态分布的等高线,不适用于相关项

Python BoxPlot 错误 - 'Series' 对象没有属性 'boxplot'

python - Django 向装饰器添加可选参数

python - 如何复制 dask 数据框?

python - 将 numpy 数组绘制为直方图