计算Matplotlib文本旋转

3

我正在尝试弄清楚如何在matplotlib中旋转文本以对齐绘图中的曲线,但我还没有找到哪些变换可以给出正确的坐标系,使得旋转文本以匹配数据坐标中的特定斜率。这里是一个简单的示例,画一条线并尝试沿着它对齐一些文本:

# Make some really non-square figure
plt.figure(figsize=(2,5))

# Draw some line between two points
pB=np.array((0,0))
pA=np.array((1,2))
pC=(pA+pB)/2
plt.plot(*zip(pA,pB))

# All the transforms at our disposal
tD=plt.gca().transData
tA=plt.gca().transAxes
tF=plt.gcf().transFigure

# Transform the endpoints of the line two some coordinate system
pA,pB=[
        ##### What goes here???
        p    # <- trivial no transform
        #tD.transform(p)
        #tA.inverted().transform(tD.transform(p))
        #tF.inverted().transform(tD.transform(p))
    for p in (pA,pB)]

# Then calculate the angle of the line
rise,run=pA-pB
rot=(180/np.pi)*np.arctan(rise/run)

# Draw some text at that angle
plt.text(pC[0],pC[1],'hi there',rotation=rot,
         horizontalalignment='center',verticalalignment='bottom');

无论我尝试什么,文本仍然朝向错误的方向:
[此图像为上述无变换情况,在Jupyter笔记本中使用%matplotlib inline选项呈现。]

enter image description here


如果你仔细想一下,文本的旋转角度是一个绝对的度量,当曲线的角度取决于轴的比例时。为了快速观察,改变绘图窗口的大小。因此,我猜测旋转角度的计算应该涉及到轴的信息。 - Uncle Ben Ben
@UncleBenBen 我同意这个直觉,在问题中,我选择了一个非常狭窄的图像尺寸,特别是为了使错位明显。尽管如此,上面代码中尝试的所有三个变换都考虑了这些信息,但仍然没有正确捕捉到角度,所以我很困惑。 - Sam Bader
1个回答

4

根据评论建议,您可能希望包括抽象表示(轴大小)与实际图像(图像大小)之间的比例关系。当曲线的角度取决于轴的刻度时,文本的旋转角度是绝对测量值。

# define the figure size
fig_x, fig_y = 4, 8
plt.figure(figsize=(fig_x, fig_y))

# Draw some line between two points
pB = np.array((0, 0))
pA = np.array((1, 2))
pC = (pA+pB)/2
plt.plot(*zip(pA, pB))

# Calculate the angle of the line
dx, dy = pA-pB
# --- retrieve the 'abstract' size
x_min, x_max = plt.xlim()
y_min, y_max = plt.ylim()
# --- apply the proportional conversion
Dx = dx * fig_x / (x_max - x_min)
Dy = dy * fig_y / (y_max - y_min)
# --- convert gaps into an angle
angle = (180/np.pi)*np.arctan( Dy / Dx)

# Draw  text at that angle
plt.text(pC[0], pC[1], 'it worked', rotation=angle,
         horizontalalignment='center', verticalalignment='bottom')
plt.show()

enter image description here


谢谢!这个代码完美地运行了,我会标记它为已接受的答案!但是如果您能够理解为什么这个数学公式与“tF.inverted().transform(tD.transform(p))”不同,我会很感兴趣。因为您上面的代码就是我认为这些转换链在幕后所做的事情,即从数据坐标系转换到图形坐标系。 - Sam Bader

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