You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib:解决坐标轴缩放不同时旋转Patch变形问题

解决坐标轴缩放不同时旋转Patch保持屏幕矩形的问题

当坐标轴x、y缩放比例不同时,直接基于ax.transData旋转Patch会导致形状变形——这是因为旋转是在数据坐标系下执行的,会受坐标轴缩放差异影响。要让旋转后的Patch在屏幕上保持矩形,需要在各向同性的空间中完成旋转操作,具体实现步骤如下:

  1. 计算坐标轴缩放补偿因子:通过数据范围与坐标轴显示区域的尺寸,算出x、y方向单位数据对应的屏幕长度比例,得到y轴的补偿缩放系数,消除坐标轴的缩放差异。
  2. 构建复合变换链:先将数据坐标转换为补偿后的各向同性空间,执行旋转,再转换回原数据坐标系。

修改后的代码如下:

import matplotlib.pyplot as plt
import matplotlib.patches as patches    
import matplotlib as mpl

fig = plt.figure()
ax = fig.add_subplot(111)

r1 = patches.Rectangle((0,0), 20, 200, color="blue", alpha=0.50)
r2 = patches.Rectangle((0,0), 20, 200, color="red",  alpha=0.50)

# 计算坐标轴的缩放补偿因子,让y轴单位数据的屏幕长度与x轴一致
x_range = ax.get_xlim()[1] - ax.get_xlim()[0]
y_range = ax.get_ylim()[1] - ax.get_ylim()[0]
bbox = ax.get_window_extent()
ax_width, ax_height = bbox.width, bbox.height
y_scale = (x_range / ax_width) / (y_range / ax_height)

# 构建复合变换:数据坐标 → 补偿y缩放 → 旋转 → 还原y缩放 → 数据坐标
transform = (
    ax.transData.inverted()
    + mpl.transforms.Affine2D().scale(1, y_scale)
    + mpl.transforms.Affine2D().rotate_deg(-45)
    + mpl.transforms.Affine2D().scale(1, 1/y_scale)
    + ax.transData
)

r2.set_transform(transform)

ax.add_patch(r1)
ax.add_patch(r2)

plt.xlim(-20, 60)
plt.ylim(-100, 300)

plt.grid(True)

plt.show()

关键说明

  • ax.get_window_extent()用于获取坐标轴的显示区域像素尺寸,结合数据范围计算出x、y方向的缩放差异,得到的y_scale可以将数据空间转换为各向同性的等价空间。
  • 复合变换的逻辑是先消除坐标轴的缩放差异,在均匀空间中完成旋转,再还原缩放回到原数据坐标系,这样旋转操作就不会导致Patch在屏幕上变形,始终保持矩形形状。

内容的提问来源于stack exchange,提问作者snakeslayer09

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 13:16:11