无法使用rotate_around()在特定点旋转matplotlib补丁对象
我正在尝试使用rotate_around()和rotate_deg_around()这两个函数,让一个matplotlib的矩形补丁对象围绕一个特定的点旋转。但是,补丁总是围绕原点旋转。我不太确定怎么才能让补丁对象围绕我指定的点旋转。
下面是我的代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib as mpl
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(-0.05,1);ax.set_ylim(-0.05,1);
grid('on');
#Rotate rectangle patch object
ts = ax.transData
tr = mpl.transforms.Affine2D().rotate_deg_around(0.2,0.5,10)
t= ts + tr
rec0 = patches.Rectangle((0.2,0.5),0.25,0.2,alpha=0.5)
ax.add_patch(rec0)
#Rotated rectangle patch
rect1 = patches.Rectangle((0.2,0.5),0.25,0.2,color='blue',alpha=0.5,transform=t)
ax.add_patch(rect1);
#The (desired) point of rotation
ax.scatter([0.0,0.2],[0.0,0.5],c=['g','r'],zorder=10)
txt = ax.annotate('Desired point of rotation',xy=(0.2,0.5),fontsize=16,\
xytext=(0.25,0.35),arrowprops=dict(arrowstyle="->",connectionstyle="arc3,rad=-.2"))
txt2 = ax.annotate('Actual point of rotation',xy=(0.0,0.0),fontsize=16,\
xytext=(0.15,0.15),arrowprops=dict(arrowstyle="->",connectionstyle="arc3,rad=.2"))
plt.show()
这是上面代码的输出结果:
我也尝试过进行平移、围绕原点旋转和再平移回来。但是,平移的变换也没有成功。任何关于简单平移的帮助或示例都会非常有用。
谢谢。
3 个回答
0
看起来在保存的时候,Ipython会改变图层的显示。旋转矩形的变换是依赖于显示坐标的,而这个坐标在缩放或者改变图层的时候会发生变化,比如在交互窗口中放大。
我们可以直接在数据坐标中旋转矩形。详细信息可以查看这个链接:在Python中旋转图形(补丁)并应用颜色
同时,我们需要使用“ax.set_aspect('equal')”来避免旋转后的矩形变形。
0
@David Zwicker,感谢你给我指明了方向。下面的代码在交互模式下运行得很好(也就是说,可以调整图形窗口的大小),无论是独立执行还是在Ipython QtConsole环境中执行都没问题。请看下面嵌入的图形。不过,它在Ipython的webnotebook环境中还是不行!如果有人能提供帮助或想法,那就太好了。谢谢。
#Imports
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['figure.dpi'] = 80 # default = 80
mpl.rcParams['savefig.dpi'] = 80 # default = 100
import matplotlib.patches as patches
import numpy as np
#Need to ensure that the figure.dpi (for displaying figure window) and
#savefig.dpi are consistent.
def redraw(event):
"""Redraw the plot on a resize event"""
if np.size(plt.get_figlabels()):
#Need to check if figure is closed or not and only then do the following
#operations. Else, the following operations will create a new figure
ax.clear()
drawRectangles(ax)
fig.canvas.draw()
else:
pass
def drawRectangles(ax):
"""Function to draw the normal and rotated patch in the transformed domain"""
#Transform for data coordinates to display coordinates
td2dis = ax.transData
coords = td2dis.transform([0.2, 0.5])
#rotate transform
tr = mpl.transforms.Affine2D().rotate_deg_around(coords[0], coords[1], 10)
t = td2dis + tr
rec0 = patches.Rectangle((0.2,0.5),0.25,0.2,color='blue',alpha=0.5)
ax.add_patch(rec0)
#Rotated rectangle patch
rect1 = patches.Rectangle((0.2,0.5),0.25,0.2,color='blue',alpha=0.5,transform=t)
ax.add_patch(rect1);
plt.grid()
figSize = (8,6)
fig = plt.figure("Patch rotate",figsize=figSize)
ax = fig.add_subplot(111)
ax.set_xlim(0,1);ax.set_ylim(0,1);
fig.canvas.mpl_connect('resize_event', redraw)
drawRectangles(ax)
plt.savefig("myfigure.png")
plt.show()
这里是上面代码的一些示例:
使用代码中的savefig( )函数保存的图像:
使用导航面板中的保存按钮保存的图像:
在调整大小后,使用导航面板中的保存按钮保存的图像:
5
你旋转的坐标不是数据坐标。你需要先对它们进行转换,也就是说:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib as mpl
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(-0.05,1);ax.set_ylim(-0.05,1);
plt.grid('on');
#Rotate rectangle patch object
ts = ax.transData
coords = ts.transform([0.2, 0.5])
tr = mpl.transforms.Affine2D().rotate_deg_around(coords[0], coords[1], 10)
t= ts + tr
rec0 = patches.Rectangle((0.2,0.5),0.25,0.2,alpha=0.5)
ax.add_patch(rec0)
#Rotated rectangle patch
rect1 = patches.Rectangle((0.2,0.5),0.25,0.2,color='blue',alpha=0.5,transform=t)
ax.add_patch(rect1);
#The (desired) point of rotation
ax.scatter([0.0,0.2],[0.0,0.5],c=['g','r'],zorder=10)
txt = ax.annotate('Desired point of rotation',xy=(0.2,0.5),fontsize=16,\
xytext=(0.25,0.35),arrowprops=dict(arrowstyle="->",connectionstyle="arc3,rad=-.2"))
txt2 = ax.annotate('Actual point of rotation',xy=(0.0,0.0),fontsize=16,\
xytext=(0.15,0.15),arrowprops=dict(arrowstyle="->",connectionstyle="arc3,rad=.2"))
plt.show()
补充:
显然,这段代码只在交互式显示时有效,但在窗口调整大小或保存图形时就不行了。看看这两张图片的对比: