matplotlib中Poly3DCollection图的透明度

时间:2013-09-19 14:42:12

标签: python matplotlib transparency scatter-plot

我正在尝试用Python的神话般的Matplotlib包绘制一些对象。这些对象包括使用plt.scatter()实现的点和使用Poly3DCollection实现的补丁。我希望补丁具有轻微的透明度,以便可以看到补丁后面的点和边缘。

这里是我已经生成的代码和图。似乎我几乎在那里,只是缺少透明度的特征。有趣的是,如果我首先绘制Ploy3DCollection以及之后的scatter点,可以看到点,但不是边缘。

有人向我提出建议吗?

enter image description here

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

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x = [0, 2, 1, 1]
y = [0, 0, 1, 0]
z = [0, 0, 0, 1]

vertices = [[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]]

tupleList = zip(x, y, z)

poly3d = [[tupleList[vertices[ix][iy]] for iy in range(len(vertices[0]))] for ix in range(len(vertices))]
ax.scatter(x,y,z)
ax.add_collection3d(Poly3DCollection(poly3d, facecolors='w', linewidths=1, alpha=0.5))

plt.show()

5 个答案:

答案 0 :(得分:11)

我对OP代码做了一些修改,并使透明度有效。似乎Poly3DCollection的facecolors参数会覆盖透明度参数,因此解决方案是在单独调用Poly3DCollection.set_colorPoly3DCollection.set_facecolor时设置颜色:

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

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x = [0, 2, 1, 1]
y = [0, 0, 1, 0]
z = [0, 0, 0, 1]

vertices = [[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]]

tupleList = zip(x, y, z)

poly3d = [[tupleList[vertices[ix][iy]] for iy in range(len(vertices[0]))] for ix in range(len(vertices))]
ax.scatter(x,y,z)
collection = Poly3DCollection(poly3d, linewidths=1, alpha=0.2)
face_color = [0.5, 0.5, 1] # alternative: matplotlib.colors.rgb2hex([0.5, 0.5, 1])
collection.set_facecolor(face_color)
ax.add_collection3d(collection)

plt.show()

有趣的是,如果您使用collection.set_edgecolor('k')明确设置边缘颜色,则边缘也会遵循透明度设置。

答案 1 :(得分:8)

我找到了一个很好的解决方法:在绘制数据之后,在顶部绘制另一个具有相同颜色和较轻线条样式的绘图。我使用Poly3DCollection代替Line3DCollection,因此不会绘制任何面。结果看起来非常符合预期。

请参阅下面的新图和创建它的脚本。

enter image description here

from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x = [0, 2, 1, 1]
y = [0, 0, 1, 0]
z = [0, 0, 0, 1]

vertices = [[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]]

tupleList = zip(x, y, z)

poly3d = [[tupleList[vertices[ix][iy]] for iy in range(len(vertices[0]))] for ix in range(len(vertices))]
ax.scatter(x,y,z)
ax.add_collection3d(Poly3DCollection(poly3d, facecolors='w', linewidths=1, alpha=0.5))
ax.add_collection3d(Line3DCollection(poly3d, colors='k', linewidths=0.2, linestyles=':'))

plt.show()

答案 2 :(得分:3)

非常感谢Chilichiller和Julian。你的例子对我来说非常有用,因为我正在研究一个关于使用matplotlib进行矩阵三维表示的小项目,而且Poly3DCollection似乎适合这项任务。

一点点,可能对未来的读者有用。 在Python 3中运行示例会产生TypeError:'zip'对象不可订阅。

最简单的解决方案是在对list()的调用中包装zip的返回值(如“Dive Into Python 3”所示:http://www.diveintopython3.net/porting-code-to-python-3-with-2to3.html)。

答案 3 :(得分:2)

此错误已在新的matplotlib中修复。我正在运行1.5.1版本。

您可以通过运行python来查看您的版本,然后执行:

import matplotlib
matplotlib.__version__

您可以使用pip获取matplotlib。如果您使用的是Ubuntu,请从终端运行:

sudo apt-get install python-pip
sudo pip install matplotlib

答案 4 :(得分:0)

这里是一个仅使用一次对Poly3DCollection的调用的版本,其中edgecolors='k'控制线条的颜色,facecolors='w'控制面孔的颜色。请注意Matplotlib如何用较浅的灰色为多边形后面的边缘着色。

enter image description here

from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x = [0, 2, 1, 1]
y = [0, 0, 1, 0]
z = [0, 0, 0, 1]

vertices = [[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]]

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

poly3d = [[tupleList[vertices[ix][iy]] for iy in range(len(vertices[0]))] for ix in range(len(vertices))]
ax.scatter(x,y,z)
ax.add_collection3d(Poly3DCollection(poly3d, edgecolors='k', facecolors='w', linewidths=1, alpha=0.5))

plt.show()

警告Poly3DCollection的API令人困惑:接受的关键字参数是colorsedgecoloredgecolors,{{ 1}}和facecolor(使用别名和修饰符定义多个kwarg表示同一件事,其中{s对facecolorsfacecolor是可选的)。