2012-10-15 23 views
85

Uczę się, jak używać mplot3d do generowania ładnych wykresów danych 3D i jestem do tej pory szczęśliwy. W tej chwili próbuję zrobić małą animację obracającej się powierzchni. W tym celu muszę ustawić pozycję kamery dla projekcji 3D. Myślę, że to musi być możliwe, ponieważ powierzchnia może być obracana za pomocą myszy, gdy interaktywnie korzysta z matplotlib. Ale jak mogę to zrobić ze skryptu? Znalazłem wiele transformacji w mpl_toolkits.mplot3d.proj3d, ale nie mogłem dowiedzieć się, jak używać tych do moich celów i nie znalazłem żadnego przykładu dla tego, co próbuję zrobić.jak ustawić "pozycję kamery" dla wykresów 3D za pomocą python/matplotlib?

+0

Notatka dla tych, zastanawiając się, jak obracać interaktywnie w jupyter notebooka: możesz użyć '% matplotlib notebook' – YvesgereY

Odpowiedz

103

"Pozycja kamery" brzmi tak, jakbyś chciał dostosować wysokość i kąt azymutu, które są używane do wyświetlania wykresu 3D. Użyłem poniższego skryptu, aby najpierw utworzyć fabułę, a następnie ustaliłem dobrą wysokość, lub elev, z której można wyświetlić moją fabułę. Następnie dostosowałem kąt azymutu lub azim, aby zmienić cały 360deg wokół mojego wykresu, zapisując liczbę w każdym przypadku (i zwracając uwagę, który kąt azymutu, gdy zapisałem wykres). W przypadku bardziej skomplikowanej panoramicznej kamery można dostosować zarówno wysokość, jak i kąt, aby uzyskać pożądany efekt.

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

Pokonaj mnie! Na marginesie są one dostępne jako właściwości 'ax.elev' i' ax.azim'. Mogłeś także napisać 'ax.azim = ii' lub nawet' ax.azim + = 1', aby osiągnąć ten sam efekt. –

+0

Przepraszam, że pokonałem cię, ale mam do czynienia z uczciwymi punktami. To także tylko fragment kodu, w pętli for było więcej niż tylko view_init i savefig. =) – cosmosis

+2

Dzięki kosmozie i Joe, właśnie tego szukałem. Ponieważ wiedziałem już, czego szukać, znalazłem również ax.dist, który - razem z ax.azim i ax.elev - pozwala ustawić pozycję kamery we współrzędnych biegunowych. –

9

Co byłoby przydatne, to zastosowanie pozycji Camera do nowej działki. Więc działam, a następnie przesuwaj wątek za pomocą myszy zmieniającej odległość. Następnie spróbuj skopiować widok zawierający odległość na innym wykresie. Uważam, że axx.ax.get_axes() pobiera mi obiekt ze starym .azim i .elev.

w Pythonie ...

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 

Później 3d wykres ...

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

EDIT 1 ... OK, pozycja kamery jest niewłaściwy sposób myślenia dotyczący wartości .dist . Przejaśnia wszystko jako rodzaj mnożnika skalarnego hackey dla całego wykresu.

Działa to na powiększenie/zoom zdania:

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 

Później Graph ...

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 za wywołanie mnożenia skalarnego skalarnego. To bardzo denerwujące, jeśli masz nadzieję na perspektywę. – user5920660