Получить координаты повернутого патча (прямоугольника) matplotlib

#matplotlib

#python #matplotlib #исправление

Вопрос:

Я хочу добиться следующего:

  • 1) получить координаты повернутого патча
  • 2) получить все точки патча (здесь: прямоугольник)
  • ** У меня сложилось впечатление, что повернутый прямоугольник не имеет 90 градусов между гранями. Это просто визуализация?

Мой фрагмент ниже. Координаты повернутого патча такие же, как и у оригинала.. Как добиться 1) и 2)?

 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)

trafo = mpl.transforms.Affine2D().rotate_around(8,4,angle)   ax.transData
r2.set_transform(trafo)

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

plt.xlim(0,15)
plt.ylim(0,15)

plt.grid(False)

plt.show()
print(r1.get_bbox())
print(r1.get_xy())
print(r2.get_bbox()) # why are they the same as for r1?
print(r2.get_xy())
#print(r1.get_all_points()) # how to achieve it?
 

Комментарии:

1. Обязательным условием для отображения повернутого прямоугольника под прямым углом на экране было бы иметь равный аспект между двумя осями, например plt.gca().set_aspect("equal") .

Ответ №1:

Координаты прямоугольника

A Rectangle определяется через пару координат нижнего левого угла (x, y), а также ширину и высоту. Чтобы получить координаты его углов, вы можете

  • вычислите их по углу, ширине и высоте,
     r1 = patches.Rectangle((8,4), 5,3)
    ax.add_patch(r1)
    coords = np.array([r1.get_xy(), [r1.get_x() r1.get_width(), r1.get_y()],
                       [r1.get_x() r1.get_width(), r1.get_y() r1.get_height()],
                       [r1.get_x(), r1.get_y() r1.get_height()]])
    print(coords)
     
  • получить их из преобразованного пути,
     r1 = patches.Rectangle((8,4), 5,3)
    ax.add_patch(r1)
    coords = r1.get_patch_transform().transform(r1.get_path().vertices[:-1])
    print(coords)
     

В обоих случаях напечатанный результат будет

 [[  8.   4.]
 [ 13.   4.]
 [ 13.   7.]
 [  8.   7.]]
 

Вы также можете получить две точки нижнего левого и верхнего правого угла из ограничивающей рамки прямоугольника (поскольку прямоугольник сам по себе является прямоугольником),

 r1 = patches.Rectangle((8,4), 5,3)
ax.add_patch(r1)
coords = r1.get_bbox().get_points()
print(coords)
 

с приведет к

 [[  8.   4.]
 [ 13.   7.]]
 

Преобразованные координаты прямоугольника.

Теперь, если вы преобразуете прямоугольник, вышеупомянутые методы должны учитывать преобразование, чтобы обеспечить правильные координаты преобразованного прямоугольника.

  • преобразовать полученные вручную координаты,
     r2 = patches.Rectangle((8,4), 5,3)
    
    trafo = mpl.transforms.Affine2D().rotate_around(8,4,angle)
    r2.set_transform(trafo   ax.transData)
    ax.add_patch(r2)
    coords = np.array([r2.get_xy(), [r2.get_x() r2.get_width(), r2.get_y()],
     [r2.get_x() r2.get_width(), r2.get_y() r2.get_height()],
     [r2.get_x(), r2.get_y() r2.get_height()]])
    print(trafo.transform(coords))
     
  • преобразуйте координаты, полученные из пути
     r2 = patches.Rectangle((8,4), 5,3)
    
    trafo = mpl.transforms.Affine2D().rotate_around(8,4,angle)
    r2.set_transform(trafo   ax.transData)
    ax.add_patch(r2)
    
    coords = r2.get_patch_transform().transform(r2.get_path().vertices[:-1])
    print(trafo.transform(coords))
     

В этих случаях напечатанные координаты будут

 [[  8.           4.        ]
 [ 11.53553391   7.53553391]
 [  9.41421356   9.65685425]
 [  5.87867966   6.12132034]]
 

Или, в случае получения координат из ограничивающей рамки

 coords = r2.get_bbox().get_points()
print(trafo.transform(coords))
 

С принтами

 [[ 8.          4.        ]
 [ 9.41421356  9.65685425]]