2016-06-02 1 views
1

Dans ma quête pour obtenir des polygones 3D en quelque sorte à réellement complot, je suis tombé sur le script suivant (EDIT: légèrement modifié): Plotting 3D Polygons in python-matplotlibTraçage 3D Polygones en Python 3

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

Mais quand je lance que je reçois le message d'erreur suivant:

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

Il semble que cela peut être une chose Python 2 vs 3, comme je suis en cours d'exécution en Python 3, et ce poste est de cinq ans. Donc, j'ai changé le troisième à la dernière ligne:

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

VERTS maintenant apparaît dans la liste des variables, mais je reçois encore une erreur:

TypeError: zip argument #1 must support iteration 

Quoi? Comment puis-je réparer ça?

Répondre

1

Vous devez utiliser Poly3DCollection au lieu de 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() 

enter image description here

+0

Oops - je ne ai pas mentionne que j'essayais déjà Poly3DCollection. Encore une fois, le zipping est ce qui cause l'erreur. Je ne sais pas comment réparer ça. – Phys251

5

J'ai eu un problème similaire avec la Zipping. Je soutiens la thèse que c'est une chose python 2.x vs 3.x.

Cependant, j'ai trouvé quelque part qui fonctionne apparemment:

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

Je l'ai donc fait deux changements:

  1. remplacé la ligne: from matplotlib.collections import Poly3DCollection par: from matplotlib.mplot3.art3d import Poly3DCollection.

    Je ne sais pas où votre déclaration d'importation provient, mais il ne semble pas fonctionner pour moi

  2. changé la ligne: verts = list(zip(x,y,z)) à verts = [list(zip(x, y, z))]

D'une certaine façon, ce dernier semble travailler. Je viens de commencer avec python, je ne peux pas offrir une explication de fer. Cependant, rien ne va plus: la classe Poly3DCollection nécessite comme premier paramètre d'entrée une "collection", d'où une liste de listes. Dans ce cas, seule la liste est donnée, ce qui est supposé ainsi raté un niveau. En ajoutant un autre niveau (via le [...]) cela a fonctionné.

J'ai aucune idée si cette explication est logique, mais il s'intègre intuitivement à moi;)

Ces modifications semblent fonctionner, car ce code crée le polygone 3D souhaité (je l'ai remarqué que, depuis cette est mon premier post, je ne suis pas autorisé à poster une preuve de la pudding figure ....)

espère que cela a été utile,

Sincères salutations

+0

Vous avez raison, 'zip()' est le problème. En Python 2, 'zip()' retourne directement une ancienne liste, que ** matplotlib ** peut digérer. En Python 3, 'zip()' a été modifié pour retourner un itérateur, pour une utilisation dans des contextes où tous les éléments ne sont pas nécessaires en même temps (ce qui peut occuper beaucoup de mémoire) ou atteindre la fin. Cette fonction ** matplotlib ** ne peut pas digérer un itérateur, donc 'list()' aplatit l'itérateur dans une liste et le fait fonctionner à nouveau. – blubberdiblub