Saya belajar bagaimana menggunakan mplot3d untuk menghasilkan plot data 3d yang bagus dan sejauh ini saya cukup senang. Apa yang saya coba lakukan saat ini adalah sedikit animasi dari permukaan yang berputar. Untuk tujuan itu, saya perlu menetapkan posisi kamera untuk proyeksi 3D. Saya rasa ini harus dimungkinkan karena permukaan dapat diputar menggunakan mouse saat menggunakan matplotlib secara interaktif. Tapi bagaimana saya bisa melakukan ini dari skrip? Saya menemukan banyak transformasi di mpl_toolkits.mplot3d.proj3d tetapi saya tidak dapat menemukan cara menggunakan ini untuk tujuan saya dan saya tidak menemukan contoh apa pun untuk apa yang saya coba lakukan.
python
matplotlib
mplot3d
Andreas Bleuler
sumber
sumber
%matplotlib notebook
Jawaban:
Dengan "posisi kamera", sepertinya Anda ingin menyesuaikan ketinggian dan sudut azimuth yang Anda gunakan untuk melihat plot 3D. Anda dapat mengatur ini dengan
ax.view_init
. Saya telah menggunakan skrip di bawah ini untuk pertama-tama membuat plot, kemudian saya menentukan ketinggian yang baik, atauelev
, untuk melihat plot saya. Saya kemudian menyesuaikan sudut azimuth, atauazim
, untuk memvariasikan 360deg penuh di sekitar plot saya, menyimpan gambar di setiap contoh (dan mencatat sudut azimuth mana saat saya menyimpan plot). Untuk pan kamera yang lebih rumit, Anda dapat menyesuaikan elevasi dan sudut untuk mendapatkan efek yang diinginkan.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)
sumber
ax.elev
danax.azim
. Anda juga bisa saja menulisax.azim = ii
atau bahkanax.azim += 1
mendapatkan efek yang sama.Apa yang berguna adalah menerapkan posisi Kamera ke plot baru. Jadi saya plot, lalu pindahkan plot dengan mouse mengubah jarak. Kemudian coba untuk meniru tampilan termasuk jarak di plot lain. Saya menemukan bahwa axx.ax.get_axes () memberi saya objek dengan .azim dan .elev lama.
DI 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
Kemudian grafik 3d ...
ax2.view_init(elev=ele, azim=azm) #Works! ax2.dist=dst # works but always 10 from axx
EDIT 1 ... Oke, posisi Kamera adalah cara berpikir yang salah tentang nilai .dist. Ini naik di atas segalanya sebagai semacam pengganda skalar hackey untuk seluruh grafik.
Ini berfungsi untuk perbesaran / zoom tampilan:
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
Grafik Selanjutnya ...
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]) #...
sumber
Coba kode berikut untuk menemukan posisi kamera yang optimal
Pindahkan sudut pandang plot menggunakan tombol keyboard seperti yang disebutkan dalam klausa if
Gunakan print untuk mendapatkan posisi kamera
def move_view(event): ax.autoscale(enable=False, axis='both') koef = 8 zkoef = (ax.get_zbound()[0] - ax.get_zbound()[1]) / koef xkoef = (ax.get_xbound()[0] - ax.get_xbound()[1]) / koef ykoef = (ax.get_ybound()[0] - ax.get_ybound()[1]) / koef ## Map an motion to keyboard shortcuts if event.key == "ctrl+down": ax.set_ybound(ax.get_ybound()[0] + xkoef, ax.get_ybound()[1] + xkoef) if event.key == "ctrl+up": ax.set_ybound(ax.get_ybound()[0] - xkoef, ax.get_ybound()[1] - xkoef) if event.key == "ctrl+right": ax.set_xbound(ax.get_xbound()[0] + ykoef, ax.get_xbound()[1] + ykoef) if event.key == "ctrl+left": ax.set_xbound(ax.get_xbound()[0] - ykoef, ax.get_xbound()[1] - ykoef) if event.key == "down": ax.set_zbound(ax.get_zbound()[0] - zkoef, ax.get_zbound()[1] - zkoef) if event.key == "up": ax.set_zbound(ax.get_zbound()[0] + zkoef, ax.get_zbound()[1] + zkoef) # zoom option if event.key == "alt+up": ax.set_xbound(ax.get_xbound()[0]*0.90, ax.get_xbound()[1]*0.90) ax.set_ybound(ax.get_ybound()[0]*0.90, ax.get_ybound()[1]*0.90) ax.set_zbound(ax.get_zbound()[0]*0.90, ax.get_zbound()[1]*0.90) if event.key == "alt+down": ax.set_xbound(ax.get_xbound()[0]*1.10, ax.get_xbound()[1]*1.10) ax.set_ybound(ax.get_ybound()[0]*1.10, ax.get_ybound()[1]*1.10) ax.set_zbound(ax.get_zbound()[0]*1.10, ax.get_zbound()[1]*1.10) # Rotational movement elev=ax.elev azim=ax.azim if event.key == "shift+up": elev+=10 if event.key == "shift+down": elev-=10 if event.key == "shift+right": azim+=10 if event.key == "shift+left": azim-=10 ax.view_init(elev= elev, azim = azim) # print which ever variable you want ax.figure.canvas.draw() fig.canvas.mpl_connect("key_press_event", move_view) plt.show()
sumber