mplot3d 视图角度#
如何定义视图角度#
3D 绘图中视口“相机”的位置由三个角度定义:仰角(elevation)、方位角(azimuth)和翻滚角(roll)。从该位置,它始终指向绘图框体的中心。角度方向是常见约定,与 PyVista 和 MATLAB 相同。请注意,正翻滚角会顺时针旋转视图平面,因此 3D 坐标轴将看起来逆时针旋转。

使用鼠标旋转绘图将控制方位角、仰角和翻滚角,并且所有这三个角度都可以通过编程设置
import matplotlib.pyplot as plt
ax = plt.figure().add_subplot(projection='3d')
ax.view_init(elev=30, azim=45, roll=15)
主要视图平面#
要直接查看主要视图平面,所需的仰角、方位角和翻滚角如下面“展开”的绘图所示。这些在 mplot3d.axes3d.Axes3D.view_init
API 中有进一步说明。

鼠标旋转#
3D 绘图可以通过拖动鼠标进行重新定位。有多种方法可以实现这一点;鼠标旋转的样式可以通过设置 rcParams["axes3d.mouserotationstyle"]
(默认值:'arcball'
)来指定,详见使用样式表和 rcParams 定制 Matplotlib。
在 v3.10 之前,2D 鼠标位置直接对应于方位角和仰角;MATLAB 也是这样做的。要保持这种方式,请设置 mouserotationstyle: azel
。这种方法对于球坐标图(其中 z 轴是特殊轴)效果很好;但是,当沿着 z 轴向下看时,它会导致一种“万向节锁死”现象:绘图对鼠标移动的反应会因当前具体方向而异。此外,“翻滚角”无法控制。
作为替代方案,有多种鼠标旋转样式,其中鼠标操控虚拟“轨迹球”。最简单的形式(mouserotationstyle: trackball
)是轨迹球围绕与鼠标运动垂直的平面内轴旋转(就像轨迹球上放着一个板子;板子本身的朝向是固定的,但你可以用鼠标拖动板子,从而旋转球体)。这种方式比 azel
样式更自然;但是,绘图不能轻易围绕视图方向旋转——必须以与所需旋转方向相反的手性圆周移动鼠标,这与直觉相悖。
另一种轨迹球类型是沿着虚拟球体上的最短弧线旋转(mouserotationstyle: sphere
)。使用它,围绕视图方向旋转非常简单:抓住球体边缘而不是中心。
Ken Shoemake 的 ARCBALL [Shoemake1992] 也可用(mouserotationstyle: Shoemake
);它类似于 sphere
样式,但没有滞后现象,即,将鼠标返回到原始位置,图形也会返回到其原始方向;旋转与鼠标移动路径的细节无关,这可能是理想的。然而,Shoemake 的 arcball 以鼠标移动角速度的两倍旋转(这非常明显,尤其是在调整翻滚角时),并且它缺乏明显的机械对应物;可以说,与路径无关的旋转并不自然(尽管方便),可能需要一些时间来适应。因此,这是一个权衡。
Henriksen 等人 [Henriksen2002] 提供了概述。总结如下:
样式 |
传统 [1] |
包含翻滚角 [2] |
均匀 [3] |
路径无关 [4] |
机械对应物 [5] |
azel |
✔️ |
❌ |
❌ |
✔️ |
✔️ |
trackball |
❌ |
✓ [6] |
✔️ |
❌ |
✔️ |
sphere |
❌ |
✔️ |
✔️ |
❌ |
✔️ |
arcball |
❌ |
✔️ |
✔️ |
✔️ |
❌ |
您可以使用以下方法尝试各种鼠标旋转样式之一:
import matplotlib as mpl
mpl.rcParams['axes3d.mouserotationstyle'] = 'trackball' # 'azel', 'trackball', 'sphere', or 'arcball'
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
ax = plt.figure().add_subplot(projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
plt.show()
或者,创建一个名为 matplotlibrc
的文件,其内容为:
axes3d.mouserotationstyle: trackball
(或任何其他样式,而不是 trackball
),然后运行任何 3D 绘图 示例。
虚拟轨迹球、球体或弧球的大小可以通过设置 rcParams["axes3d.trackballsize"]
(默认值:0.667
)来调整。这指定了获得给定旋转角度(靠近中心时)所需的鼠标移动量,并控制球体或弧球的边缘位置(距离中心多远,从而距离绘图边缘多近)。大小以坐标轴边界框的单位指定,即,要使弧球覆盖整个边界框,请将其设置为 1。大约 2/3 的大小似乎效果不错;这是默认值。
两种弧球(mouserotationstyle: sphere
和 mouserotationstyle: arcball
)都有明显的边缘;可以通过指定边框宽度 rcParams["axes3d.trackballborder"]
(默认值:0.2
)来使其边缘不那么突兀。这有点像 Gavin Bell 的弧球,它最初是为 OpenGL [Bell1988] 编写的,并用于 Blender 和 Meshlab。Bell 的弧球通过一个双曲线扩展了弧球的球面控制表面;两者平滑连接。然而,双曲线一直延伸到绘图的边缘之外。在 mplot3d 的球体和弧球样式中,边框延伸到半径为 trackballsize/2 + trackballborder
的位置。超出边框后,样式像原始样式一样工作:它只控制翻滚角。大约 0.2 的边框宽度似乎效果不错;这是默认值。要获得原始 Shoemake 的带尖锐边框的弧球,请将边框宽度设置为 0。对于类似于 Bell 弧球的扩展边框,其中从弧球到边框的过渡发生在 45°,将边框宽度设置为 \(\sqrt 2 \approx 1.414\)。边框是一个圆弧,像甜甜圈一样圆柱形地环绕在弧球球体周围,与球体平滑连接,非常类似于 Bell 的双曲线。
Ken Shoemake,《ARCBALL:一种使用鼠标指定三维旋转的用户界面》,载于 Graphics Interface '92 会议论文集,1992,第 151-156 页,https://doi.org/10.20380/GI1992.18
Gavin Bell,在 GLUT (OpenGL Utility Toolkit) 库随附的示例中,markkilgard/glut
Knud Henriksen, Jon Sporring, Kasper Hornbæk,《虚拟轨迹球再探》,载于 IEEE Transactions on Visualization and Computer Graphics, 第 10 卷,第 2 期,2004 年 3-4 月,第 206-216 页,https://doi.org/10.1109/TVCG.2004.1260772 [全文];