为什么Matplotlib中圆形/补丁集合的旋转点会改变

3

3种不同的旋转度:

enter image description here

你好,我正在尝试旋转Matplotlib Collections.PatchCollection(圆形)。我无法保持相同的旋转点。

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

如何在旋转后保持相同的旋转点? 先行致谢。

看起来它每次都在使用相同的旋转点:(0,0)(左下角)。 - Arthur Tacca
如果我没错的话,对于Collections.PatchCollection/Circle来说,使用<rotate_deg_around>比<rotate_deg>更好,正如r-beginners所说。 - cbenagaraj
我完全同意!我只是在争论你的文本和图表,它说每次旋转的旋转点都不同(你的绿色箭头)。实际上,每次旋转的旋转点相同(你的绿色箭头位置都不正确:它们应该指向底部左侧轴交叉点)。只是不是你想要的旋转点。如果您想围绕不同的点旋转,则解决方法是使用rotate_deg_around() - Arthur Tacca
2个回答

4
如果您不指定旋转中心,则旋转将围绕 (0,0) 进行。要围绕某个点旋转,您可以首先减去其坐标,进行旋转,然后再添加这些坐标。
下面的示例展示了差异:
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()

plot


4

要进行旋转,似乎需要使用.rotate_deg_around(x,y,degree)进行指定。 这个例子在xy=0.5处旋转了90度。

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

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接