Reputation: 29
3 different rotation degree:
Hi, I am trying to rotate Matplotlib Collections.PatchCollection (circles). I could not keep the same point of rotation.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections
import matplotlib as mpl
num = 5
sizes = 0.01, 0.01, 0.01, 0.01, 0.01
xy = (.5,.7),(.5,.6),(.5,.5),(.5,.4),(.5,.3)
print(xy)
# Note that the patches won't be added to the axes, instead a collection will
patches = [plt.Circle(center, size) for center, size in zip(xy, sizes)]
patches2 = [plt.Circle(center, size) for center, size in zip(xy, sizes)]
fig, ax = plt.subplots(1,1)
coll = matplotlib.collections.PatchCollection(patches, facecolors='none')
coll2 = matplotlib.collections.PatchCollection(patches2, facecolors='None')
ax.add_collection(coll)
ax.add_collection(coll2)
t2 = mpl.transforms.Affine2D().rotate_deg(12.5) + ax.transData
coll2.set_transform(t2)
plt.show()
How to keep the same point of rotation after rotation? Thanks in advance
Upvotes: 3
Views: 577
Reputation: 35205
To rotate it, it seems to be specified with .rotate_deg_around(x,y,degree)
.
This example is rotated 90 degrees at xy=0.5.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections
import matplotlib as mpl
num = 5
sizes = 0.01, 0.01, 0.01, 0.01, 0.01
xy = (.5,.7),(.5,.6),(.5,.5),(.5,.4),(.5,.3)
print(xy)
# Note that the patches won't be added to the axes, instead a collection will
patches = [plt.Circle(center, size) for center, size in zip(xy, sizes)]
patches2 = [plt.Circle(center, size) for center, size in zip(xy, sizes)]
fig, ax = plt.subplots(1,1)
coll = matplotlib.collections.PatchCollection(patches, facecolors='none')
coll2 = matplotlib.collections.PatchCollection(patches2, facecolors='None')
ax.add_collection(coll)
ax.add_collection(coll2)
coords = [0.5,0.5]
# t2 = mpl.transforms.Affine2D().rotate_deg(12.5) + ax.transData
# t2 = mpl.transforms.Affine2D().rotate_deg(2.5) + ax.transData
t2 = mpl.transforms.Affine2D().rotate_deg_around(coords[0], coords[1], 90) + ax.transData
coll2.set_transform(t2)
plt.show()
Upvotes: 4
Reputation: 80449
If you don't specify a center of rotation, the rotation will be around (0,0). To rotate around a certain point, you can first subtract its coordinates, do the rotation and then add these coordinates again.
The following example shows the difference:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections
import matplotlib as mpl
sizes = [0.01, 0.01, 0.01, 0.01, 0.01]
xy = [(.5, .7), (.5, .6), (.5, .5), (.5, .4), (.5, .3)]
xc, yc = xy[-1] # (.5, .3)
fig, axes = plt.subplots(ncols=2, figsize=(12, 4))
for ax in axes:
patches = [plt.Circle(center, size) for center, size in zip(xy, sizes)]
coll = matplotlib.collections.PatchCollection(patches, facecolors='none')
ax.add_collection(coll)
cmap = plt.get_cmap('rainbow')
for angle in np.arange(12.5, 360, 12.5):
patches2 = [plt.Circle(center, size) for center, size in zip(xy, sizes)]
coll2 = matplotlib.collections.PatchCollection(patches2, facecolors=cmap(angle / 360))
if ax == axes[0]:
t2 = mpl.transforms.Affine2D().rotate_deg(angle) + ax.transData
ax.set_title('rotation around (0, 0)')
else:
t2 = mpl.transforms.Affine2D().translate(-xc, -yc).rotate_deg(angle).translate(xc, yc) + ax.transData
ax.set_title(f'rotation around {xc, yc}')
coll2.set_transform(t2)
ax.add_collection(coll2)
ax.autoscale()
plt.show()
Upvotes: 4