Seite 1 von 1

Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Dienstag 17. Februar 2015, 20:44
von scandium
Hallo Zusammen,

ich möchte gerne Faces die im Wavefront (*.obj) Format vorliegen, mit einen 3D Plot darstellen und mit definierten Farben versehen.
Es geht um Vierecke die wie folgt definiert werden.

4x Knoten Koordinaten pro Face: (v ,x, y, z)
v 0.031500 -0.015000 0.170910
v 0.029352 -0.015155 0.174785
v 0.031500 -0.015000 0.173228
v 0.029420 -0.015145 0.172856

1x Face das alle vier Knoten anspricht
f 1 2 3 4

Ich hatte probiert, das erst manuell über den Surface Plot darzustellen, jedoch ohne Erfolg.
Ein Scatter Plot also nur die Ausgabe der Knoten funktioniert.
Wie könnte ich am besten solche Flächen / Faces darstellen?

Hiermit hatte ich bisher erfolglos probiert:

Code: Alles auswählen

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

xs=np.array([1,1,5,5])  
ys=np.array([1,5,5,1])
zs=np.array([0,0,0,0])

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
#ax.scatter(xs, ys, zs)
ax.plot_surface(xs, ys, zs)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()

Danke für eure Bemühungen.

Edit: Code Tags hinzugefügt

Re: Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Dienstag 17. Februar 2015, 20:53
von EyDu
Schau dir dazu mal Poly3dCollection an.

Und bitte setze deine Code in Code-Tags, dann ist dein Code auch lesbar.

Re: Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Mittwoch 18. Februar 2015, 23:38
von scandium
@ EyDu

folgendes Beispiel funktioniert schon mal:

Code: Alles auswählen

from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
element1=[[(0, 0, 0), (1, 0, 0), (1, 0, 1), (0, 0 , 1)]]
ax.add_collection3d(Poly3DCollection((element1)))
plt.show()
Ich würde jedoch gerne die Knotenpunktkoordinaten aus einen Numpy Array nehmen und hätte mir da folgendes überlegt:

Code: Alles auswählen

from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt
import numpy as np
p1=np.array([[0,0,0]])
p2=np.array([[1,0,0]])
p3=np.array([[1,0,1]])
p4=np.array([[0,0,1]])
fig = plt.figure()
ax = Axes3D(fig)
ax.add_collection3d(Poly3DCollection((p1,p2,p3,p4)))
plt.show()
Das Skript läuft durch ohne Fehlermeldung, allerdings wird im Plot nichts dargestellt.
Was muss ich ändern um den Plot korrekt darzustellen?

Re: Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Mittwoch 18. Februar 2015, 23:45
von EyDu
Ich habe es nicht ausprobiert, aber ich würde einfach mal vermuten, dass du ein nx3-Array in einer Liste übergeben musst. Deine zweite Variante stimmt auf jeden Fall schon nicht mit den Dimensionen der ersten überein.

Re: Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Donnerstag 19. Februar 2015, 10:19
von scandium
p1 bis p4 liegen doch im Format 1x3 Array vor? Oder meinst du das es ein Array nx3 für alle Punkte sein müsste, die nacher über Idizes :,0 ect zugewiesen werden?

Re: Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Donnerstag 19. Februar 2015, 10:59
von BlackJack
@scandium: Im ersten Beispiel übergibst Du etwas der Form 1×4×3 und im zweiten 4×1×3. Das erste funktioniert, das zweite nicht. Und wenn ich da mal nach Dokumentation herangehe, dann übergibt man da ja mehere Polygone, also ist die äusserste Dimension die Anzahl der Polygone. Jedes Element beschreibt ein Polygon. Also muss jedes Element aus einer Sequenz von Koordinatentripeln bestehen. Im ersten Fall haben wir 1 Polygon, mit 4 Koordinaten. Und im zweiten Fall haben wir 4 Polygone mit jeweils 1er Koordinate. Wie sollte denn ein Polygon gezeichnet werden das nur aus einem Punkt besteht?

Re: Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Freitag 20. Februar 2015, 09:58
von scandium
@BlackJack

Ich habe das erste Beispiel umgeändert und es sieht nun wie folgt aus:

Code: Alles auswählen

from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt
import numpy as np
p1=np.array([[0,0,0]])
p2=np.array([[1,0,0]])
p3=np.array([[1,0,1]])
p4=np.array([[0,0,1]])
fig = plt.figure()
ax = Axes3D(fig)
element2=[[(p1[0,0], p1[0,1],p1[0,2]), (p2[0,0], p2[0,1], p2[0,2]), (p3[0,0], p3[0,1], p3[0,2]), (p4[0,0], p4[0,1] , p4[0,2])]]
ax.add_collection3d(Poly3DCollection((element2)))
plt.show()
Es funktioniert soweit...jedoch sieht es nicht so recht elegant aus, speziell "element2.
Gibt es noch eine übersichtlichere Weise das "element2" zu definieren?

Re: Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Freitag 20. Februar 2015, 10:14
von EyDu
Ja, indem du etwas über die Dimension deiner Arrays nachdenkst? Warum sind die Punkte 1x3-Arrays und nicht einfach Arrays mit drei Werten? Dann musst du auch nicht jeden Wert in Zeile 11 sinnlos aufzählen, sondern kannst die direkt die Punkte verbinden. Noch einfacher ist es natürlich, wenn du meinen Tipp mit dem nx3-Array ausprobiert hättest. Das funktioniert nämlich wunderbar.

Re: Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Freitag 20. Februar 2015, 10:27
von BlackJack
@scandium: Klar geht das eleganter. Als erstes könnte man den Quelltext mal so formatieren das man die Struktur auch erkennen kann:

Code: Alles auswählen

    element2 = [
        [
            (p1[0, 0], p1[0, 1], p1[0, 2]),
            (p2[0, 0], p2[0, 1], p2[0, 2]),
            (p3[0, 0], p3[0, 1], p3[0, 2]),
            (p4[0, 0], p4[0, 1], p4[0, 2]),
        ]
    ]
Da fällt dann ziemlich schnell auf das der erste Index immer 0 ist und der zweite der Reihe nach jede Komponente aus dem inneren Array der Punkte holt. Also letztendlich landest Du bei Tupeln die wie die inneren Arrays aufgebaut sind. Was soll das? Da kann man doch gleich die inneren Arrays verwenden:

Code: Alles auswählen

    element2 = [[p1[0], p2[0], p3[0], p4[0]]]
Und dann stellt sich die Frage warum `p1` bis `p4` so komisch aussehen? Was soll dieses äussere Array bei den Koordinaten? Das macht doch keinen Sinn. Ein Punkt besteht doch aus drei Komponenten und nicht aus einer Komponente die drei Komponenten enthält. Wenn die `p*`\s ”normal” definiert wären dann würde `element2` (blöder Name übrigens, `polygons` wäre besser) so aussehen:

Code: Alles auswählen

    element2 = [[p1, p2, p3, p4]]

Re: Viereck-Elemente mit Matlplotlib 3D darstellen.

Verfasst: Mittwoch 25. Februar 2015, 13:34
von scandium
@BlackJack: Ich habe die Arrays jetzt normal definiert, also ein Klammerausdruck entfernt.
Die Form "element = [[p1, p2, p3, p4]]" sieht gleich viel eleganter aus.

Danke.