Прозрачность для участка Poly3DCollection в matplotlib
Я пытаюсь привлечь некоторые объекты со сказочным пакетом Matplotlib для Python. Эти объекты состоят из точек, реализованных с помощью 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()
Ответы
Ответ 1
Я нашел хорошее обходное решение: после построения данных сделайте еще один сюжет сверху с тем же цветом и более легким стилем линии. Вместо Ploy3DCollection
я использую Line3DCollection
, поэтому никакие грани не отображаются. Результат выглядит очень ожидаемым.
См. ниже новый график и script, создав его.
![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
Я сделал небольшую модификацию кода OP и получил прозрачность. Похоже, что аргумент facecolors для Poly3DCollection переопределяет аргумент прозрачности, поэтому решение заключалось в том, чтобы установить цвет в отдельный вызов либо Poly3DCollection.set_color
, либо Poly3DCollection.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')
, ребра также будут соблюдать настройку прозрачности.
Ответ 3
Большое спасибо Чилихиллеру и Джулиану. Ваши примеры очень полезны для меня в настоящее время, потому что я работаю над небольшим проектом о трехмерном представлении матриц с matplotlib, и Poly3DCollection кажется подходящим для задачи.
Небольшая заметка, возможно, может быть полезна будущим читателям.
Запуск ваших примеров в Python 3 дает TypeError: объект "zip" не подлежит расшифровке.
Самое простое решение - обернуть возвращаемое значение zip в вызове list() (как указано в "Dive Into Python 3": http://www.diveintopython3.net/porting-code-to-python-3-with-2to3.html).
Ответ 4
Эта ошибка была исправлена в новом matplotlib. Я запускаю версию 1.5.1.
Вы можете увидеть свою версию, запустив python, а затем выполните:
import matplotlib
matplotlib.__version__
Вы можете получить matplotlib, используя pip. Если вы используете Ubuntu, запустите его с терминала:
sudo apt-get install python-pip
sudo pip install matplotlib