尺寸不相等时的 Matplotlib 3DPlot 额外线条 [英] Matplotlib 3DPlot Extra Lines when Dimensions not Equal

查看:31
本文介绍了尺寸不相等时的 Matplotlib 3DPlot 额外线条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑此MWE:

 将matplotlib.pyplot导入为plt从mpl_toolkits.mplot3d导入Axes3D将numpy导入为np从 matplotlib 导入 cmn = 15m = 12x = np.linspace(-5,5,n)y = np.linspace(-5,5,m)Z = np.zeros((m,n))对于我在xrange(m)中:对于xrange(n)中的j:Z[i, j] = x[j]**2 + y[i]**2###绘制表面###无花果= plt.figure()ax = fig.add_subplot(111, 投影='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 不相等.结果图有一些奇怪的线条垂下,以及奇怪的颜色:

这里发生了什么,我该如何预防?

解决方案

与matplotlib中的2D,3D图不同,许多

上面的例子给 rstrides 和 cstrides 的值为 10.如果你把它增加太多(比如 80),问题就很明显了:

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

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

Note in particular that the dimensions n and m are not equal. The resulting plot has some weird lines hanging down, as well as strange coloring:

What's going on here, and how can I prevent this?

解决方案

Unlike 2D, 3D plots in matplotlib have a lot of shortcomings. Let me quote one of the answers in 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.

For your particular problem (and notice that I don't think this has anything to do with different sizes in each direction) I would advise you to increase your surface shape (even if artificially) and play around with the number of strides until you obtain something that is satisfactory:

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

,which results in this:

The example above give rstrides and cstrides a value of 10. Should you increase it too much (let's say 80) and the problem becomes obvious:

Other option is for you to follow the recommendation of matplotlib FAQ itself and check Mayavi. Notice, however, that mayavi still does not support Python 3. Personally, if you need something quick to work with, I would recommend PyQtGraph.

这篇关于尺寸不相等时的 Matplotlib 3DPlot 额外线条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆