如何使用python / matplotlib为3d绘图设置“相机位置”?

时间:2022-09-10 21:58:23

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.

我正在学习如何使用mplot3d来生成漂亮的三维数据图表,到目前为止我非常高兴。我现在要做的是旋转表面的一点动画。为此,我需要为3D投影设置摄像机位置。我想这一定是可行的,因为在交互式使用matplotlib时可以使用鼠标旋转表面。但是如何从脚本中执行此操作?我在mpl_toolkits.mplot3d.proj3d中发现了很多变换,但是我无法找到如何将这些变换用于我的目的,我没有找到任何我想要做的例子。

2 个解决方案

#1


110  

By "camera position," it sounds like you want to adjust the elevation and the azimuth angle that you use to view the 3D plot. 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.

通过“摄像机位置”,您可能会想要调整用于查看3D绘图的高程和方位角。我已经使用下面的脚本来创建情节,然后我确定了一个很好的高度或高度,从中可以查看我的情节。然后我调整了方位角或azim,以改变我的绘图周围的整个360度,保存每个实例的数字(并注意我保存绘图时的方位角)。对于更复杂的摄像机平移,您可以调整高度和角度以获得所需的效果。

    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)

#2


10  

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.

将相机位置应用于新绘图将会更方便。所以我绘制,然后用鼠标改变距离移动图表。然后尝试复制包含另一个图上距离的视图。我发现axx.ax.get_axes()通过旧的.azim和.elev获取了一个对象。

IN PYTHON...

在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...

后来的3d图...

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.

编辑1 ...好的,相机位置是关于.dist值的错误思考方式。它作为整个图形的一种hackey标量乘数在所有东西之上。

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

#1


110  

By "camera position," it sounds like you want to adjust the elevation and the azimuth angle that you use to view the 3D plot. 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.

通过“摄像机位置”,您可能会想要调整用于查看3D绘图的高程和方位角。我已经使用下面的脚本来创建情节,然后我确定了一个很好的高度或高度,从中可以查看我的情节。然后我调整了方位角或azim,以改变我的绘图周围的整个360度,保存每个实例的数字(并注意我保存绘图时的方位角)。对于更复杂的摄像机平移,您可以调整高度和角度以获得所需的效果。

    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)

#2


10  

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.

将相机位置应用于新绘图将会更方便。所以我绘制,然后用鼠标改变距离移动图表。然后尝试复制包含另一个图上距离的视图。我发现axx.ax.get_axes()通过旧的.azim和.elev获取了一个对象。

IN PYTHON...

在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...

后来的3d图...

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.

编辑1 ...好的,相机位置是关于.dist值的错误思考方式。它作为整个图形的一种hackey标量乘数在所有东西之上。

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