Matplotlib指定figsize时如何让3D绘图满画布且保等轴比无裁剪
解决方法
裁剪问题由两个原因导致:默认figure预留了大量内边距,没有完全利用设置的figsize空间;自定义3D投影缩放后,场景范围超出了坐标轴默认的裁剪边界。修改代码如下即可解决:
关键修改点
- 调用
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)移除figure所有内边距,让坐标轴占满全部画布空间 - 给
plot_surface传入clip_on=False关闭曲面自身的裁剪 - 设置
ax.clip_on = False关闭整个坐标轴区域的裁剪,避免超出边界的模型部分被裁 - 可根据实际显示效果微调投影矩阵的最后一个缩放系数,适配当前画布的宽高比
- 若不需要显示坐标轴刻度、标签,可额外添加
ax.axis('off'),完全隐藏坐标轴元素,进一步提升空间利用率
修改后完整代码
from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import numpy as np fig = plt.figure(figsize=(5, 2.5)) # 移除所有内边距 fig.subplots_adjust(left=0, right=1, bottom=0, top=1) ax = fig.add_subplot(projection='3d') # 微调投影缩放系数适配2:1的画布比例 ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), np.diag([1, 1, 1, 0.45])) u = v = np.linspace(0, 2 * np.pi, 50) u, v = np.meshgrid(u, v) X = np.cos(v) * (6 - (5/4 + np.sin(3 * u)) * np.sin(u - 3 * v)) Y = (6 - (5/4 + np.sin(3 * u)) * np.sin(u - 3 * v)) * np.sin(v) Z = -np.cos(u - 3 * v) * (5/4 + np.sin(3 * u)) # 关闭曲面裁剪 ax.plot_surface(X, Y, Z, rstride=1, cstride=1, color=[0.7] * 3, linewidth=0.25, edgecolor="k", clip_on=False) ax.set_box_aspect([ub - lb for lb, ub in (getattr(ax, f'get_{a}lim')() for a in 'xyz')]) # 关闭坐标轴整体裁剪 ax.clip_on = False # 可选:隐藏坐标轴元素 # ax.axis('off') plt.show()
内容的提问来源于stack exchange,提问作者Davide_sd
相关产品推荐
相关产品推荐

