在 Python 3 中绘制 3D 多边形

Plotting 3D Polygons in Python 3

在我寻求以某种方式让 3D 多边形实际绘制时,我遇到了以下脚本(编辑:稍作修改):Plotting 3D Polygons in python-matplotlib

from mpl_toolkits.mplot3d import Axes3D
from matplotlib.collections import Poly3DCollection
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
x = [0,1,1,0]
y = [0,0,1,1]
z = [0,1,0,1]
verts = [zip(x, y,z)]
ax.add_collection3d(Poly3DCollection(verts),zs=z)
plt.show()

但是当我 运行 时,我收到以下错误消息:

TypeError: object of type 'zip' has no len()

看来这可能是Python2对3的事情,因为我运行宁在Python3,那post就是5年老的。所以我将倒数第三行更改为:

verts = list(zip(x, y, z))

现在 verts 出现在变量列表中,但我仍然收到错误消息:

TypeError: zip argument #1 must support iteration

什么?我该如何解决这个问题?

您必须使用 Poly3DCollection 而不是 PolyCollection:

from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
x = [0,1,1,0]
y = [0,0,1,1]
z = [0,1,0,1]
verts = [zip(x,y,z)]
ax.add_collection3d(Poly3DCollection(verts), zs=z)
plt.show()

我在压缩时遇到了类似的问题。我支持这个论点,它是 python 2.x vs 3.x 的东西。

但是,我找到了一个显然有效的地方:

from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt

fig = plt.figure()
ax = Axes3D(fig)
x = [0, 1, 1, 0]
y = [0, 0, 1, 1]
z = [0, 1, 0, 1]
verts = [list(zip(x, y, z))]
print(verts)
ax.add_collection3d(Poly3DCollection(verts), zs='z')
plt.show()

因此我做了两个改变:

  1. 替换了行: from matplotlib.collections import Poly3DCollection 经过: from matplotlib.mplot3.art3d import Poly3DCollection.

    我不知道你的导入语句来自哪里,但它似乎对我不起作用

  2. 更改了行:verts = list(zip(x,y,z))verts = [list(zip(x, y, z))]

不知何故,后者似乎有效。刚开始使用 python,我无法提供铁定的解释。然而,这里什么也没有:class Poly3DCollection 需要一个 "collection" 作为第一个输入参数,因此是一个列表列表。在这种情况下,只给出列表,假定它错过了一个级别。通过向其添加另一个级别(通过 [...])它起作用了。

我不知道这个解释是否合理,但它符合我的直觉 ;)

这些修改似乎有效,因为此代码创建了所需的 3D 多边形(我注意到,因为这是我的第一个 post,我不允许 post 证明-布丁图.... )

希望这有用,

亲切的问候

这是一个当前的解决方案,以防您遇到错误 ValueError: not enough values to unpack (expected 3, got 1),因为 verts 在其他解决方案中的构造方式:

from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
x = [0,1,1,0]
y = [0,0,1,1]
z = [0,1,0,1]
verts = [[xx,yy,zz] for xx,yy,zz in zip(x,y,z)]     # NEW
ax.add_collection3d(Poly3DCollection(verts))
plt.show()