2012-10-15 9 views
85

Ich lerne, wie mplot3d verwendet wird, um schöne 3D-Daten zu erzeugen, und ich bin bisher ziemlich glücklich. Was ich im Moment versuche, ist eine kleine Animation einer rotierenden Oberfläche. Zu diesem Zweck muss ich eine Kameraposition für die 3D-Projektion einstellen. Ich denke, das muss möglich sein, da eine Oberfläche mit der Maus gedreht werden kann, wenn Matplotlib interaktiv verwendet wird. Aber wie kann ich das aus einem Skript machen? Ich habe eine Menge Transformationen in mpl_toolkits.mplot3d.proj3d gefunden, aber ich konnte nicht herausfinden, wie ich diese für meinen Zweck benutze und ich fand kein Beispiel für das, was ich versuche zu tun.Wie setzt man "camera position" für 3D-Plots mit Python/Matplotlib?

+0

Randnotiz für die fragen, wie diejenigen, interaktiv in jupyter Notebook drehen: Sie verwenden können, '% matplotlib notebook' – YvesgereY

Antwort

103

Bei "Kameraposition" klingt es so, als ob Sie die Höhe und den Azimutwinkel anpassen möchten, mit denen Sie die 3D-Darstellung anzeigen. Ich habe das folgende Skript verwendet, um zuerst das Diagramm zu erstellen, und dann habe ich eine gute Höhe oder elev ermittelt, von der aus ich mein Diagramm ansehen kann. Dann passte ich den Azimutwinkel an, oder azim, um die vollen 360 Grad um mein Diagramm zu variieren und speicherte die Zahl bei jeder Instanz (und notiere den Azimutwinkel, während ich das Diagramm speicherte). Bei einem komplizierteren Kameraschwenk können Sie sowohl die Höhe als auch den Winkel anpassen, um den gewünschten Effekt zu erzielen.

from mpl_toolkits.mplot3d import Axes3D 
    ax = Axes3D(fig) 
    ax.scatter(xx,yy,zz, marker='o', s=20, c="goldenrod", alpha=0.6) 
    for ii in xrange(0,360,1): 
     ax.view_init(elev=10., azim=ii) 
     savefig("movie%d.png" % ii) 
+17

Beat mich dazu! Nebenbei bemerkt, sind diese als "ax.elev" - und "ax.azim" -Eigenschaften verfügbar. Sie könnten auch einfach 'ax.azim = ii' oder sogar' ax.azim + = 1' geschrieben haben, um denselben Effekt zu erzielen. –

+0

Entschuldigung, ich habe dich geschlagen, aber überall sind faire Punkte. Dies ist auch nur ein Coding-Auszug von mir, es gab mehr innerhalb dieser for-Schleife als nur view_init und savefig. =) – cosmosis

+2

Dank Kosmose und Joe, das war genau das, was ich gesucht habe. Da ich nun wusste, worauf ich achten musste, fand ich auch ax.dist, das - zusammen mit ax.azim und ax.elev - die Kameraposition in Polarkoordinaten einstellen lässt. –

9

Was wäre praktisch wäre, die Kamera-Position auf eine neue Handlung anzuwenden. Also ich plotten, dann bewegen Sie die Handlung herum mit der Maus die Entfernung ändern. Versuchen Sie dann, die Ansicht einschließlich der Entfernung auf einem anderen Diagramm zu replizieren. Ich finde, dass axx.ax.get_axes() mir ein Objekt mit der alten .azim und .elev bekommt.

IN PYTHON ...

axx=ax1.get_axes() 
azm=axx.azim 
ele=axx.elev 
dst=axx.dist  # ALWAYS GIVES 10 
#dst=ax1.axes.dist # ALWAYS GIVES 10 
#dst=ax1.dist  # ALWAYS GIVES 10 

Später 3D-Grafik ...

ax2.view_init(elev=ele, azim=azm) #Works! 
ax2.dist=dst      # works but always 10 from axx 

EDIT 1 ... OK, Kameraposition ist die falsche Denkweise der .dist Wert über . Es rangiert über allem als eine Art Hackey-Skalarmultiplikator für den gesamten Graphen.

Dies ist für die Vergrößerung/Zoom der Ansicht funktioniert:

xlm=ax1.get_xlim3d() #These are two tupples 
ylm=ax1.get_ylim3d() #we use them in the next 
zlm=ax1.get_zlim3d() #graph to reproduce the magnification from mousing 
axx=ax1.get_axes() 
azm=axx.azim 
ele=axx.elev 

Graph später ...

ax2.view_init(elev=ele, azim=azm) #Reproduce view 
ax2.set_xlim3d(xlm[0],xlm[1])  #Reproduce magnification 
ax2.set_ylim3d(ylm[0],ylm[1])  #... 
ax2.set_zlim3d(zlm[0],zlm[1])  #... 
+0

+1 zum Ausrufen der Hacky-Skalarmultiplikation. Es ist sehr ärgerlich, wenn Sie auf Perspektive hoffen. – user5920660