在Matplotlib多边形中手动旋转

时间:2018-06-22 15:40:31

标签: matplotlib

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
print(mpl.get_backend())

def rotate(xy,deg,rp):
    """xy is the path, deg is degrees of rotation, rp is the rotation point"""
    #translate first, rotate, then retranslate
    xy = xy-rp
    i=0
    while i<len(xy):
        xy[i][0]= xy[i][0]*np.cos(np.deg2rad(deg))-(xy[i][1]*np.sin(np.deg2rad(deg)))
        xy[i][1]= xy[i][0]*np.sin(np.deg2rad(deg))+xy[i][1]*np.cos(np.deg2rad(deg))
        i+=1
    return xy+rp


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

f,(ax) = plt.subplots(1,1,figsize=(8,8))
f.subplots_adjust(hspace=0,wspace=0)
ax.set_xlim(0,10)
ax.set_ylim(-2,8)
plt.grid(True)
plt.xticks(np.arange(0, 10+1, 0.5))
plt.yticks(np.arange(-2, 8+1, 0.5))


def xy(height=1.3,width=2,center=(0,0)):

    num = []
    ran1 = range(0,361)
    b=height#height
    a=width#width
    i=360
    femur_dict = {}
    xcen=center[0]
    ycen=center[1]
    for counter in range(0,360):
        num.append(np.array([a*np.cos(np.deg2rad(counter))+xcen,b*np.sin(np.deg2rad(ran1[counter]))+ycen]))
        i-=1
    return num

scale = 1
t2 = mpl.patches.Polygon(xy(center=(7,7),height=1*scale,width=0.25*scale),fc="blue")
td2dis = ax.transData
coords = td2dis.transform(t2.get_xy()[270])
    #rotate transform
tr = mpl.transforms.Affine2D().rotate_deg_around(coords[0], coords[1], -90)
t = td2dis + tr
t3=mpl.patches.Polygon(t2.get_xy(),fc='green',alpha=0.5,zorder=10000)
t3.set_transform(t)

t4 = mpl.patches.Polygon(rotate(xy(center=(7,7),height=1*scale,width=0.25*scale),45,t2.get_xy()[270]),fc="red")

ax.add_patch(t4)

ax.add_patch(t2)
ax.add_patch(t3)


plt.show()

我想手动旋转对象。应用转换后,我需要访问对象的原始坐标。如何访问t3的变换坐标?

红色为手动旋转,不起作用,但功能正确。 Matplotlib要求太多。 matplotlib is requiring above and beyond what an intuitive rotation should be.

1 个答案:

答案 0 :(得分:0)

首先,您在rotate函数中出错,因为y坐标考虑了新计算的x坐标,而不是原始坐标。一个简单的解决方法是

def rotate(xy,deg,rp):
    """xy is the path, deg is degrees of rotation, rp is the rotation point"""
    #translate first, rotate, then retranslate
    xy = xy-rp
    i=0
    while i<len(xy):
        a = xy[i][0]*np.cos(np.deg2rad(deg))-(xy[i][1]*np.sin(np.deg2rad(deg)))
        b = xy[i][0]*np.sin(np.deg2rad(deg))+xy[i][1]*np.cos(np.deg2rad(deg))
        xy[i] = [a,b]
        i+=1
    return xy+rp

哪个会产生

enter image description here

第二,我认为您想在数据空间而不是显示空间中执行旋转。如图所示在this previous question中,这可以通过在通过ax.transData转换为显示空间之前应用 之前的旋转来完成。

所以您可能想要的是以下内容:

t2 = mpl.patches.Polygon(xy(center=(7,7),height=1,width=0.25),fc="blue")
td2dis = ax.transData
coords = t2.get_xy()[270]

tr = mpl.transforms.Affine2D().rotate_deg_around(coords[0], coords[1], -90)

t3=mpl.patches.Polygon(t2.get_xy(),fc='green',alpha=0.5,zorder=10000)
t3.set_transform(tr + td2dis)

ax.add_patch(t2)
ax.add_patch(t3)

现在,当您询问t3的“原始坐标”时,有两种可能性,

您是指数据坐标吗?

在这种情况下,它们位于tr.transform(t3.get_xy())中,其中tr是从上方旋转的角度。

您是指显示坐标吗?

这些在(tr + td2dis).transform(t3.get_xy())中。