0
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()

I want to rotate an object manually. I need to access the raw coordinates of an object after applying a transform. How do i access the transformed coordinates of t3?

The red is manual rotation and its not working but the function is coorect. Matplotlib ask too much. matplotlib is requiring above and beyond what an intuitive rotation should be.

orig2007A
  • 1
  • 1

1 Answers1

0

First of all you have an error in the rotate function, because the y coordinate takes the newly calculated x coordinte instead of the original one into account. An easy fix would be

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

Which would yield

enter image description here

Second, I think you want to perform the rotation in data space, not in display space. As shown e.g. in this previous question, this would be done by applying the rotation before transforming to display space via ax.transData.

So what you probably want is the following:

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)

Now when you ask for the "raw coordinates" of t3, there are two possibilities,

Do you mean the data coordinates?

In this case those are in tr.transform(t3.get_xy()), where tr is the rotation from above.

Do you mean the display coordinates?

Those are in (tr + td2dis).transform(t3.get_xy()).

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Great you fixed the function. I didnt notice. Unfortunately neither data coordinates or display coordinates are what I am looking for. Im looking for a function to return the coordinate (9,6) which is the furtherst point on the green oval. – orig2007A Jun 22 '18 at 18:41
  • Could be, because in your question you do not even tell what you are looking for. – ImportanceOfBeingErnest Jun 22 '18 at 18:42
  • When discussing a image like this its got to be the most intuitive data points on the graph you follow the axis ticks 9 on the x and 6 on the y. you can get the untransformed oval equivalent with get_xy. but on the transformed oval you cant get that point nore can you get it with the data coordinate technique or the display coordinate technique – orig2007A Jun 22 '18 at 18:45
  • Not sure what you mean. `tr.transform(t3.get_xy())` gives you the transformed data. – ImportanceOfBeingErnest Jun 22 '18 at 18:51
  • tr.transform(t3.get_xy())[0] = array([ -37. , 1063.41666667]) I cant find (9,6) in the data set – orig2007A Jun 22 '18 at 18:56
  • No, `print(tr.transform(t3.get_xy())[0])` results in `[ 8. 5.75]`. – ImportanceOfBeingErnest Jun 22 '18 at 18:59
  • i just dont get that number i get (-37, 1063) – orig2007A Jun 22 '18 at 19:07