Python 适当旋转标签并将其与matplotlib对齐
下面的代码将一些点放置在平面上,并从中心到每个点绘制一条线。对于每个点,都有一个标签,并希望将标签放在该点之后。因此,从中心,我们看到一条线,然后是一个点,然后是一个文本。我想把标签放在同一条线的斜率上 目前,我有这段代码,但正如您所看到的,旋转后的文本没有正确对齐。我怎样才能解决这个问题Python 适当旋转标签并将其与matplotlib对齐,python,matplotlib,Python,Matplotlib,下面的代码将一些点放置在平面上,并从中心到每个点绘制一条线。对于每个点,都有一个标签,并希望将标签放在该点之后。因此,从中心,我们看到一条线,然后是一个点,然后是一个文本。我想把标签放在同一条线的斜率上 目前,我有这段代码,但正如您所看到的,旋转后的文本没有正确对齐。我怎样才能解决这个问题 import matplotlib.pyplot as plt import numpy as np from math import * a = np.array([ [-0.108,0.414], [0.
import matplotlib.pyplot as plt
import numpy as np
from math import *
a = np.array([
[-0.108,0.414],
[0.755,-0.152],
[0.871,-0.039],
],)
labels = ["XXXXXXX", "YYYYYY", "ZZZZZZZ"]
x, y = a.T
plt.scatter(x, y)
plt.xlim(-1,1)
plt.ylim(-1,1)
ax = plt.axes()
for i in range(a.shape[0]):
px = a[i,0]
py = a[i,1]
ax.arrow(0, 0, px, py, head_width=0, head_length=0.1, length_includes_head=True)
angle = degrees(atan(py/px))
ax.annotate(labels[i], (px, py), rotation=angle)
plt.grid(True)
plt.show()
更新:
我使用了建议和修改的解决方案
text_plot_location = np.array([0.51,0.51])
trans_angle = plt.gca().transData.transform_angles(np.array((45,)),text_plot_location.reshape((1,2)))[0]
ax.annotate(labels[i], (px, py), rotation=text_plot_location)
然而,我得到了这个错误,
TypeError:unhabable type:'numpy.ndarray'
由@mapf创建的链接有点干净,但这是我想到的:
导入matplotlib.pyplot作为plt
将numpy作为np导入
a=np.array([
[-0.108,0.414],
[0.755,-0.152],
[0.871,-0.039],
],)
标签=[“XXXXXXX”、“yyyyy”、“ZZZZZZZ”]
x、 y=a.T
图,ax=plt.子批次()
最大散射(x,y)
ax.set_xlim(-1,1)
ax.set_ylim(-1,1)
直线,=最大曲线图(*a.T)
对于枚举(zip(标签,a))中的jdx(标签,点):
#找到最近的点
tmp=np.linalg.norm(a点,轴=1)
idx=np.argsort(tmp)[1]
其他=a[idx]
#计算角度
度=np.角(复数(*(点-其他)))
度=np.rad2deg(度)
ax.注释(标签、点、旋转=度、,
ha='左',va='基线',
transform=ax.transData)
ax.grid(真)
图2(图3)
我不知道为什么角度与直线不完全匹配。您在更新中犯了一个简单的错误。您需要将
trans\u angle
传递到rotation
关键字,而不是text\u plot\u location
,但是,我不确定结果是否是您要查找的
import matplotlib.pyplot as plt
import numpy as np
from math import *
a = np.array([
[-0.108,0.414],
[0.755,-0.152],
[0.871,-0.039],
],)
labels = ["XXXXXXX", "YYYYYY", "ZZZZZZZ"]
x, y = a.T
plt.scatter(x, y)
plt.xlim(-1,1)
plt.ylim(-1,1)
ax = plt.axes()
for i in range(a.shape[0]):
px = a[i, 0]
py = a[i, 1]
ax.arrow(0, 0, px, py, head_width=0, head_length=0.1,
length_includes_head=True)
text_plot_location = np.array([0.51, 0.51])
angle = degrees(atan(py / px))
trans_angle = plt.gca().transData.transform_angles(
np.array((angle,)), text_plot_location.reshape((1, 2))
)[0]
ax.annotate(labels[i], (px, py), rotation=trans_angle)
plt.grid(True)
plt.show()
不太理想,但离你想要的有点近。缺点是文本偏移的任意值为30点,该值适用于给定标签,但需要针对更长或更短的标签进行调整
import matplotlib.pyplot as plt
import numpy as np
from math import *
a = np.array([[-0.108,0.414],[0.755,-0.152],[0.871,-0.039]])
labels = ["XXXXXXX", "YYYYYY", "ZZZZZZZ"]
x, y = a.T
plt.scatter(x, y)
plt.xlim(-1,1)
plt.ylim(-1,1)
ax = plt.axes()
for i in range(a.shape[0]):
px = a[i,0]
py = a[i,1]
ax.arrow(0, 0, px, py, head_width=0, head_length=0.1, length_includes_head=True)
angle = atan(py/px)
d = (-1 if px < 0 else 1) * 30
ax.annotate(labels[i], (px, py), rotation=degrees(angle), textcoords="offset points",
xytext=(d*cos(angle), d*sin(angle)),
verticalalignment='center', horizontalalignment='center')
plt.grid(True)
plt.show()
导入matplotlib.pyplot作为plt
将numpy作为np导入
从数学导入*
a=np.数组([-0.108,0.414],[0.755,-0.152],[0.871,-0.039])
标签=[“XXXXXXX”、“yyyyy”、“ZZZZZZZ”]
x、 y=a.T
plt.散射(x,y)
plt.xlim(-1,1)
plt.ylim(-1,1)
ax=plt.axs()
对于范围内的i(a.shape[0]):
px=a[i,0]
py=a[i,1]
最大箭头(0,0,px,py,头部宽度=0,头部长度=0.1,长度包括头部=True)
角度=atan(py/px)
d=(-1,如果px<0,则为1)*30
ax.注释(标签[i],(px,py),旋转=度(角度),textcoords=“偏移点”,
xytext=(d*cos(角度),d*sin(角度)),
垂直对齐=中心,水平对齐=中心)
plt.grid(真)
plt.show()
这是否回答了您的问题?这将使标签位于线上方。在我的最后一段代码中,我有很多点,如果我把标签放在线条上面,那么对于那些有小角度的线条来说,表示方式就不好了。我理解,但是你应该能够控制文本相对于线条的偏移量。我更新了帖子。