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

如何获取Matplotlib中旋转矩形Patch的坐标与所有顶点?

解决你的Matplotlib旋转Patch问题

首先咱们先搞清楚核心问题:为什么旋转后的r2和r1的get_bbox()、get_xy()结果一致?因为Matplotlib里,Patch的原始属性(比如起始坐标、边界框)存储的是未应用变换的原始数据,你设置的trafo只是在绘制阶段对Patch做视觉变换,并没有修改Patch本身的底层坐标。要拿到旋转后的实际坐标,得手动用变换矩阵去转换原始点。

下面一步步解决你的需求和疑问:

1. 获取旋转后Patch的坐标

你可以用定义好的trafo变换对象,把原始坐标点转换为旋转后的实际坐标。比如:

  • 旋转后的起始点:用trafo.transform(r2.get_xy())直接转换原始起始点
  • 旋转后的边界框:先提取原始边界框的关键点位,再逐个应用变换

2. 获取旋转后矩形的所有顶点

先根据矩形的原始起始点、宽度、高度算出四个顶点的原始坐标,再用变换矩阵转换每个点,就能得到旋转后的顶点坐标。

3. 关于旋转后矩形边角的疑问

这不是单纯的视觉效果!默认情况下Matplotlib的坐标轴比例不是等比例的(x轴和y轴的单位长度在屏幕上显示不一致),所以旋转后的矩形看起来边角不是90度。只需要加上ax.set_aspect('equal'),让坐标轴比例一致,就能看到标准的旋转矩形了。

修改后的完整代码示例

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib as mpl
from matplotlib.transforms import Affine2D

fig = plt.figure()
ax = fig.add_subplot(111)
angle = np.deg2rad(45)

# 原始矩形
r1 = patches.Rectangle((8,4), 5,3, fill=False, color="red", alpha=0.50)
# 待旋转的矩形
r2 = patches.Rectangle((8,4), 5,3, fill=False, color="blue", alpha=0.50)

# 定义旋转变换:围绕(8,4)旋转45度,叠加轴的坐标变换
trafo = mpl.transforms.Affine2D().rotate_around(8,4,angle) + ax.transData
r2.set_transform(trafo)

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

# 设置坐标轴等比例,解决旋转后矩形边角视觉变形问题
ax.set_aspect('equal')
plt.xlim(0,15)
plt.ylim(0,15)
plt.grid(False)
plt.show()

# ---------------------- 获取旋转后的坐标和顶点 ----------------------
# 1. 获取旋转后的起始坐标
original_xy = r2.get_xy()
rotated_xy = trafo.transform(original_xy)
print(f"原始起始坐标: {original_xy}")
print(f"旋转后起始坐标: {rotated_xy}")

# 2. 获取旋转后的所有顶点
x0, y0 = r2.get_xy()
w, h = r2.get_width(), r2.get_height()
# 原始矩形的四个顶点:左下、右下、右上、左上
original_vertices = np.array([
    [x0, y0],
    [x0 + w, y0],
    [x0 + w, y0 + h],
    [x0, y0 + h]
])
# 对所有顶点应用旋转变换
rotated_vertices = trafo.transform(original_vertices)
print("\n旋转后矩形的所有顶点坐标:")
for idx, vertex in enumerate(rotated_vertices):
    print(f"顶点{idx+1}: {vertex.round(2)}")

# 3. 获取旋转后的边界框(通过顶点的极值计算)
rotated_bbox = np.array([
    [rotated_vertices[:,0].min(), rotated_vertices[:,1].min()],
    [rotated_vertices[:,0].max(), rotated_vertices[:,1].max()]
])
print("\n旋转后的边界框(左下、右上):")
print(rotated_bbox.round(2))

关键说明

  • trafo.transform()是核心:它能把原始坐标转换为经过旋转和轴映射后的实际显示坐标
  • ax.set_aspect('equal')让x、y轴单位长度一致,旋转后的矩形边角会显示为标准90度
  • 原始顶点的计算基于矩形的基础属性,变换后就能得到旋转后的准确顶点位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:31:15