come impostare la "posizione della telecamera" per i grafici 3d usando python / matplotlib?


134

Sto imparando come usare mplot3d per produrre trame carine di dati 3d e finora sono abbastanza felice. Quello che sto cercando di fare al momento è una piccola animazione di una superficie rotante. A tale scopo, devo impostare una posizione della telecamera per la proiezione 3D. Immagino che ciò debba essere possibile poiché una superficie può essere ruotata usando il mouse quando si utilizza interattivamente matplotlib. Ma come posso farlo da una sceneggiatura? Ho trovato molte trasformazioni in mpl_toolkits.mplot3d.proj3d ma non sono riuscito a scoprire come usarle per il mio scopo e non ho trovato alcun esempio di ciò che sto cercando di fare.


2
Nota a margine per quelli che si chiedono come ruotare in modo interattivo nel taccuino di Giove: è possibile utilizzare%matplotlib notebook
YvesgereY

Anche il trascinamento tenendo premuto il pulsante destro del mouse cambia la distanza della fotocamera.
LoMaPh

Per questo tipo di vizualizzazioni, proverei mayavi.
Tactopoda,

Risposte:


158

Per "posizione della telecamera" sembra che tu voglia regolare l'elevazione e l'angolo azimutale che usi per visualizzare il grafico 3D. Puoi impostarlo con ax.view_init. Ho usato lo script seguente per creare prima la trama, poi ho determinato una buona elevazione, o elev, da cui visualizzare la mia trama. Ho quindi regolato l'angolo di azimut o azim, per variare l'intera 360 ° attorno alla mia trama, salvando la figura in ogni istanza (e notando quale angolo di azimut mentre salvavo la trama). Per una panoramica più complicata, puoi regolare sia l'elevazione che l'angolazione per ottenere l'effetto desiderato.

    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)

26
Sconfiggimi! In una nota a margine, questi sono disponibili come proprietà ax.eleve ax.azim. Potresti anche aver appena scritto ax.azim = iio addirittura ax.azim += 1ottenere lo stesso effetto.
Joe Kington,

1
Mi dispiace di averti battuto, ma punti equi tutto intorno. Anche questo è solo un mio estratto di codice, in quel for-loop c'era molto di più di view_init e savefig. =)
Cosmosi

4
Grazie cosmo e Joe, era esattamente quello che stavo cercando. Dato che ora sapevo cosa cercare, ho anche trovato ax.dist che, insieme a ax.azim e ax.elev, consente di impostare la posizione della telecamera in coordinate polari.
Andreas Bleuler,

Se questa è la risposta, potresti per favore selezionarla? Grazie.
Cosmosi

12
Puoi anche impostare la distanza tra la telecamera e il punto oggetto di ax.dist = 15 (il valore predefinito è 10)
Tim

14

Ciò che sarebbe utile sarebbe applicare la posizione della videocamera a una nuova trama. Quindi complotto, quindi muovo la trama con il mouse cambiando la distanza. Quindi prova a replicare la vista includendo la distanza su un'altra trama. Trovo che axx.ax.get_axes () mi procuri un oggetto con i vecchi .azim e .elev.

IN PITONE ...

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

Grafico 3d successivo ...

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

EDIT 1 ... OK, la posizione della telecamera è il modo sbagliato di pensare riguardo al valore .dist. Funziona al di sopra di tutto come una sorta di moltiplicatore scalare hackey per l'intero grafico.

Questo funziona per l'ingrandimento / zoom della vista:

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

Grafico successivo ...

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])     #...

+1 per richiamare la moltiplicazione scalare confusa. È molto fastidioso se speravi in ​​una prospettiva.
user5920660
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.