Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to set "camera position" for 3d plots using python/matplotlib?

I'm learning how to use mplot3d to produce nice plots of 3d data and I'm pretty happy so far. What I am trying to do at the moment is a little animation of a rotating surface. For that purpose, I need to set a camera position for the 3D projection. I guess this must be possible since a surface can be rotated using the mouse when using matplotlib interactively. But how can I do this from a script? I found a lot of transforms in mpl_toolkits.mplot3d.proj3d but I could not find out how to use these for my purpose and I didn't find any example for what I'm trying to do.

like image 573
Andreas Bleuler Avatar asked Oct 15 '12 22:10

Andreas Bleuler


People also ask

Can matplotlib Pyplot be used to display 3d plots?

But at the time when the release of 1.0 occurred, the 3d utilities were developed upon the 2d and thus, we have 3d implementation of data available today! The 3d plots are enabled by importing the mplot3d toolkit. In this article, we will deal with the 3d plots using matplotlib.


2 Answers

By "camera position," it sounds like you want to adjust the elevation and the azimuth angle that you use to view the 3D plot. You can set this with ax.view_init. I've used the below script to first create the plot, then I determined a good elevation, or elev, from which to view my plot. I then adjusted the azimuth angle, or azim, to vary the full 360deg around my plot, saving the figure at each instance (and noting which azimuth angle as I saved the plot). For a more complicated camera pan, you can adjust both the elevation and angle to achieve the desired effect.

    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) 
like image 59
cosmosis Avatar answered Oct 14 '22 18:10

cosmosis


What would be handy would be to apply the Camera position to a new plot. So I plot, then move the plot around with the mouse changing the distance. Then try to replicate the view including the distance on another plot. I find that axx.ax.get_axes() gets me an object with the old .azim and .elev.

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 

Later 3d graph...

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

EDIT 1... OK, Camera position is the wrong way of thinking concerning the .dist value. It rides on top of everything as a kind of hackey scalar multiplier for the whole graph.

This works for the magnification/zoom of the view:

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 

Later 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])     #... 
like image 26
snaxxus Avatar answered Oct 14 '22 18:10

snaxxus