Matplotlib 等比例坐标轴如何只向上限方向扩展?
数据小陈
结论
anchor='SW' 不能让 adjustable='datalim' 只向右侧或上侧扩展数据范围。anchor 用来调整绘图区在可用空间中的位置。设置 adjustable='box' 时,可以让绘图区贴近左下角;设置 adjustable='datalim' 时,Matplotlib 会调整数据范围以满足等比例要求,anchor 无法指定只扩展哪一侧。
如果可以接受绘图区缩小,可以使用 adjustable='box' 和 anchor='SW'。这样会保留数据范围,并让绘图区贴近左下角。如果必须保持绘图区大小,同时保留下限并扩展上限,就需要根据绘图区的实际宽高比计算坐标范围。
保留下限并计算上限
等比例坐标要求 x、y 方向的数据跨度与绘图区宽高比相匹配。设绘图区宽高比为 r,坐标跨度应满足:
x_span / y_span = r
下面的代码先完成布局,再读取绘图区尺寸,并在保留当前下限的基础上计算上限,使当前数据范围仍能完整显示:
fig.tight_layout()
fig.canvas.draw() # 确保布局和绘图区尺寸已经确定
for ax in axs.ravel():
# 保留零作为下限;数据始终为正时适用
ax.set_xlim(left=0)
ax.set_ylim(bottom=0)
x0, x1 = ax.get_xlim()
y0, y1 = ax.get_ylim()
ratio = ax.get_window_extent().width / ax.get_window_extent().height
# 选择足够大的 x 跨度,使两个方向都能包含原坐标范围
x_span = max(x1 - x0, ratio * (y1 - y0))
y_span = x_span / ratio
ax.set_xlim(x0, x0 + x_span)
ax.set_ylim(y0, y0 + y_span)
ax.set_aspect('auto')
这里设置 set_aspect('auto'),避免 aspect 再次调整计算出的范围和绘图区尺寸。只要绘图区尺寸不变,两个方向的单位长度就相等。窗口大小、子图布局或导出尺寸改变后,需要按新的尺寸重新计算范围。
如果只处理一个子图,可以将循环中的 ax 换成对应的轴对象。代码假设数据下限为零;如果要保留其他下限,将 left=0 和 bottom=0 替换为实际下限即可。
接受绘图区缩小时的简便做法
如果允许绘图区缩小,可以直接设置:
ax.set_aspect('equal', adjustable='box', anchor='SW')
这样会保留数据坐标范围,并将绘图区锚定在左下角,但不会只扩展数据上限。adjustable='datalim' 适用于让 Matplotlib 调整数据范围以满足 aspect 的情况,anchor 无法控制单侧扩展。
备注:内容仅供参考。
