¿Cómo trazar una colección de parches 3D en matplotlib?
-
25-10-2019 - |
Pregunta
Estoy tratando de hacer una gráfica 3D en matplotlib con tres círculos, cada uno centrado en el origen y con un radio de 1, apuntando en diferentes direcciones, para ilustrar una esfera de radio 1, por ejemplo.
En 2D haría una colección de parches circulares y la agregaría a los ejes. En 3D tengo problemas para que los parches aparezcan en absoluto, y mucho menos orientarlos en diferentes direcciones.
import matplotlib
import matplotlib.pyplot as P
import mpl_toolkits.mplot3d as M3
fig = P.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
circles = matplotlib.collections.PatchCollection(
[matplotlib.patches.Circle((0, 0), 1) for count in range(3)],
offsets=(0, 0))
M3.art3d.patch_collection_2d_to_3d(circles, zs=[0], zdir='z')
ax.add_collection(circles)
P.show()
Ejecutar este programa llena toda la ventana de la trama con azul, es decir, el color de la cara de los parches, sin importar cómo gire la trama. Si me puse facecolor='none'
en el PatchCollection()
llamar, luego un vacío Axes3D
aparece.
Cosas que he probado:
- Si uso un
CircleCollection
en lugar de unPatchCollection
, no aparecen parches en absoluto. los
zs
parámetro en elpatch_collection_2d_to_3d()
la llamada es extraña; Esperaría ponerzs=0
(una coordenada z para los tres parches) ozs=[0,0,0]
(una coordenada Z separada para cada parche), pero ambos lanzan un error:ValueError: establecer un elemento de matriz con una secuencia.
Para orientar los parches de manera diferente, esperaría poder pasar algo como
zdir=['x', 'y', 'z']
Pero los resultados no son diferentes si paso eso o'z'
o['z']
.- También hubiera esperado poder hacer
ax.add_collection3d(circles, zs=[0, 0, 0], zdir=['x', 'y', 'z'])
En lugar de convertir la colección de parches de 2D a 3D, pero eso también arroja un error:AttributeRor: 'Patch3DCollection' El objeto no tiene atributo 'set_sort_zpos'
Solución
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, PathPatch
from mpl_toolkits.mplot3d import Axes3D
import mpl_toolkits.mplot3d.art3d as art3d
fig = plt.figure()
ax=fig.gca(projection='3d')
for i in ["x","y","z"]:
circle = Circle((0, 0), 1)
ax.add_patch(circle)
art3d.pathpatch_2d_to_3d(circle, z=0, zdir=i)
ax.set_xlim3d(-2, 2)
ax.set_ylim3d(-2, 2)
ax.set_zlim3d(-2, 2)
plt.show()