web-dev-qa-db-fra.com

comment définir la "position de la caméra" pour les tracés 3D à l'aide de python / matplotlib?

J'apprends à utiliser mplot3d pour produire de jolis graphes de données 3D et je suis assez heureux jusqu'à présent. Ce que j'essaie de faire en ce moment est une petite animation d'une surface en rotation. Pour ce faire, je dois définir une position de caméra pour la projection 3D. Je suppose que cela doit être possible car une surface peut être pivotée à l'aide de la souris lors de l'utilisation interactive de matplotlib. Mais comment puis-je faire cela à partir d'un script? J'ai trouvé beaucoup de transformations dans mpl_toolkits.mplot3d.proj3d mais je n'ai pas trouvé comment les utiliser pour mon but et je n'ai trouvé aucun exemple de ce que j'essaie de faire.

117
Andreas Bleuler

Par "position de la caméra", il semble que vous souhaitiez régler l'altitude et l'angle d'azimut que vous utilisez pour afficher le tracé 3D. Vous pouvez régler ceci avec ax.view_init . J'ai utilisé le script ci-dessous pour créer d'abord l'intrigue, puis j'ai déterminé une bonne élévation, ou elev, à partir de laquelle afficher mon intrigue. J'ai ensuite ajusté l'angle d'azimut, ou azim, pour faire varier les 360 degrés complets autour de mon tracé, en enregistrant la figure à chaque instance (et en notant l'angle d'azimut lors de l'enregistrement du tracé). Pour un panoramique de caméra plus complexe, vous pouvez régler l’élévation et l’angle afin d’obtenir l’effet souhaité.

    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)
136
cosmosis

Ce qui serait pratique serait d’appliquer la position de la caméra à un nouveau tracé. Donc, je trace, puis déplace la parcelle avec la souris en changeant la distance. Ensuite, essayez de reproduire la vue, y compris la distance sur un autre tracé. Je trouve que axx.ax.get_axes () me fournit un objet avec les anciens .azim et .elev.

À 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

Plus tard graphique 3d ...

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

EDIT 1 ... OK, la position de la caméra est une mauvaise façon de penser en ce qui concerne la valeur .dist. Il se superpose à tout comme une sorte de multiplicateur scalaire de hackey pour tout le graphique.

Cela fonctionne pour le grossissement/zoom de la vue:

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

Plus tard graphique ...

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