2016-06-02 21 views
1

In meiner Suche nach irgendwie 3D-Polygone zu bekommen, um tatsächlich Grundstück, ich über das folgende Skript kam (EDIT: leicht modifiziert): Plotting 3D Polygons in python-matplotlibPlotten 3D-Polygone in 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() 

Aber wenn ich laufe, dass ich die folgende Fehlermeldung:

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

Es scheint, dass dies eine 2 vs. 3 Sache Python sein kann, wie ich in Python leite 3, und das Post ist fünf Jahre alt. Also änderte ich den dritten bis letzten Zeile:

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

Jetzt zeigt sich in der Variablenliste verts, aber ich habe noch eine Fehlermeldung erhalten:

TypeError: zip argument #1 must support iteration 

Was? Wie behebe ich das?

Antwort

1

Sie haben Poly3DCollection verwenden statt 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

Bezug Oops - ich gescheitert Erwähnen Sie, dass ich Poly3DCollection bereits versucht habe. Das Zippen ist wiederum der Grund für den Fehler. Ich weiß nicht, wie ich das beheben soll. – Phys251

5

Ich habe ein ähnliches Problem mit dem Zuziehen hatte. Ich unterstütze die These, es ist eine Python 2.x vs 3.x Sache.

Allerdings habe ich irgendwo gefunden, die offenbar funktioniert:

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

ich also zwei Änderungen vorgenommen haben:

  1. ersetzt die Zeile: from matplotlib.collections import Poly3DCollection von: from matplotlib.mplot3.art3d import Poly3DCollection.

    Ich weiß nicht, wo der Import Erklärung stammt, aber es hat nicht für mich scheinen

  2. geändert, um die Linie zu arbeiten: verts = list(zip(x,y,z)) zu verts = [list(zip(x, y, z))]

Irgendwie, letztere scheint arbeiten. Nachdem ich gerade mit Python angefangen habe, kann ich keine eiserne Erklärung anbieten. Hier geht jedoch nichts: Die Klasse Poly3DCollection benötigt als ersten Eingabeparameter eine "Collection", also eine Liste von Listen. In diesem Fall wird nur eine Liste angegeben, von der angenommen wird, dass sie eine Ebene verfehlt hat. Durch Hinzufügen einer anderen Ebene (über die [...]) funktionierte es.

ich habe keine Ahnung, ob diese Erklärung Sinn macht, aber paßt es intuitiv zu mir;)

Diese Modifikationen zu funktionieren scheinen, wie dieser Code die gewünschten 3D-Polygon erzeugt (Ich habe bemerkt, dass, da diese mein erster Beitrag ist, bin ich nicht ein Proof-of-the-Pudding Figur schreiben erlaubt ....)

Hoffnung war nützlich,

Art

+0

Sie haben Recht, 'zip()' ist das Problem. In Python 2 wird mit 'zip()' direkt eine einfache alte Liste zurückgegeben, die ** matplotlib ** verdauen kann. In Python 3 wurde 'zip()' geändert, um einen Iterator zurückzugeben, der in Kontexten verwendet werden kann, in denen nicht alle Elemente gleichzeitig benötigt werden (die viel Speicher belegen können, wenn es viele gibt) oder wenn man davor aufhört, Elemente zu verbrauchen das Ende erreichen. Diese ** matplotlib ** -Funktion kann einen Iterator nicht verdauen, also flacht 'list() 'den Iterator in eine Liste und macht sie wieder funktionsfähig. – blubberdiblub