Matplotlib:如何在3D空间的XY平面内旋转椭圆?
解决3D空间中椭圆在指定平面内旋转的问题
你说得没错,Ellipse的angle参数是在2D绘图坐标系内绕椭圆中心旋转,当你用pathpatch_2d_to_3d把它映射到3D空间后,这个旋转的效果可能和你期望的“在3D目标平面内的方位角旋转”不一致——因为2D的angle是基于原始XY轴的旋转,而不是3D空间中目标平面的轴。
要实现3D空间内指定平面的椭圆旋转,我们可以通过两种方式处理:
方法1:先对2D椭圆路径做旋转变换,再映射到3D
如果你的目标是让椭圆在某个3D平面(比如你当前的x=5000平面,平行于YZ平面)内旋转,可以先对2D椭圆的路径应用旋转变换,再转换到3D空间。
修改后的代码示例:
from matplotlib.patches import Ellipse import matplotlib.pyplot as plt import mpl_toolkits.mplot3d.art3d as art3d from matplotlib.transforms import Affine2D fig = plt.figure(figsize=(10,8)) ax = fig.add_subplot(111, projection='3d') # 创建2D椭圆 p = Ellipse(xy=(6000,7000), width=2000, height=150, edgecolor='b', fc='b', lw=2) # 定义旋转变换:绕椭圆中心旋转45度(这里的角度是你想要的方位角) rotation_angle = 45 # 你可以修改这个值 transform = Affine2D().rotate_deg_around(*p.center, rotation_angle) + p.get_transform() p.set_transform(transform) # 将2D椭圆映射到3D的x=5000平面 ax.add_patch(p) art3d.pathpatch_2d_to_3d(p, z=5000, zdir="x") ax.set_xlim(0, 12500) ax.set_ylim(0, 12500) ax.set_zlim(6500, 7600) plt.show()
方法2:对3D中的patch直接应用空间旋转
如果你已经把椭圆映射到3D空间,还可以用art3d提供的旋转函数对其进行3D空间的旋转,比如绕x轴旋转(对应在x=常数的平面内旋转):
from matplotlib.patches import Ellipse import matplotlib.pyplot as plt import mpl_toolkits.mplot3d.art3d as art3d import numpy as np fig = plt.figure(figsize=(10,8)) ax = fig.add_subplot(111, projection='3d') p = Ellipse(xy=(6000,7000), width=2000, height=150, edgecolor='b', fc='b', lw=2) ax.add_patch(p) art3d.pathpatch_2d_to_3d(p, z=5000, zdir="x") # 绕x轴旋转45度(弧度制) rotation_angle = np.deg2rad(45) art3d.rotate_patch(p, rotation_angle, 'x') ax.set_xlim(0, 12500) ax.set_ylim(0, 12500) ax.set_zlim(6500, 7600) plt.show()
关键说明:
- 如果你想让椭圆在XY平面(z固定)内旋转(绕z轴旋转),只需要把
zdir设置为"z",然后用绕z轴的旋转即可:# 映射到XY平面(z=5000) art3d.pathpatch_2d_to_3d(p, z=5000, zdir="z") # 绕z轴旋转45度 art3d.rotate_patch(p, np.deg2rad(45), 'z') Ellipse的angle参数是在2D绘图时的旋转,它会改变椭圆自身的长轴方向,但当你把它映射到3D空间后,这个旋转是基于原始2D坐标系的,而不是3D空间的目标平面,所以才会出现“绕轴转动”的不符合预期的效果。
内容的提问来源于stack exchange,提问作者Dark Knight
相关产品推荐
相关产品推荐

