首页 > 解决方案 > 使用 matplotlib 正确旋转和对齐标签

问题描述

以下代码将一些点放在平面上,并从中心到每个点绘制一条线。对于每个点,都有一个标签,并希望将标签放在该点之后。因此,从中心,我们看到一条线,然后是一个点,然后是一个文本。我想将标签与直线的斜率相同。

目前,我有这个代码,但你可以看到旋转的文本没有正确对齐。我该如何解决?

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: unhashable type: 'numpy.ndarray'

标签: pythonmatplotlib

解决方案


不理想,但更接近你想要的。缺点是文本偏移的任意值 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()

在此处输入图像描述


推荐阅读