无法使用rotate_around()围绕特定点旋转matplotlib修补程序对象

时间:2013-03-21 20:38:27

标签: python 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()

以下是上述代码的输出:

enter image description here

我也尝试过翻译,rotate_about_origin和translate_back。然而,翻译变换也没有奏效。简单翻译的任何帮助/示例也将非常有用。

谢谢。

3 个答案:

答案 0 :(得分:3)

您旋转的坐标不是数据坐标。你必须先改变它们,即

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

编辑:

显然,代码仅适用于交互式显示,但不适用于调整窗口大小或保存图形的情况。比较这两个图像:

interactive display saved figure

答案 1 :(得分:0)

似乎在保存时,Ipython会更改图层。旋转矩形的转换取决于显示坐标,当缩放或更改图层时可以更改,例如,在交互式窗口中进行转换。

我们可以在数据坐标中旋转矩形。见Rotating a figure (patch) and applying colors in python

虽然我们需要“ax.set_aspect('equal')”以避免旋转的矩形变形。

答案 2 :(得分:-1)

@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()函数保存的图像: enter image description here

使用导航面板中的保存按钮保存的图像: enter image description here

重新调整大小后使用导航面板中的“保存”按钮保存的图像: enter image description here enter image description here