我正在尝试使用 matplotlib 创建雷达图。我的目标是定位每个标签,使其从不同角度指向圆心,类似于图 1 图 1 所示。但是,我目前遇到的是这个结果(图 2): 图 2 .
请告诉我如何调整我的代码以实现标签的适当旋转?提前致谢!
这是我的代码:
import math
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv('./results/zh_en_annotation_eval.csv', sep=',',
index_col=0, header='infer', encoding='utf-8')
labels = df.columns.values.tolist()
N = len(labels)
values = df.loc['r'].values.tolist()
angles = [n / float(N) * 2 * math.pi for n in range(N)] + [0]
def plot_radar_chart(ax, angles, values, label, color, alpha=0.2):
values += values[:1]
ax.plot(angles, values, linewidth=1, linestyle='solid', label=label, color=color)
ax.fill(angles, values, alpha=alpha, color=color)
fig, ax = plt.subplots(figsize=(16, 12), subplot_kw={'projection': 'polar'})
ax.set_theta_offset(math.pi / 2)
ax.set_theta_direction(-1)
ax.set_xticks(angles[:-1])
for i, angle in enumerate(angles[:-1]):
angle_deg = np.degrees(angle)
rotation = angle_deg + 90
label_position = 1.1
ax.text(angle, label_position, labels[i], transform=ax.transData,
ha='center', va='center', rotation=rotation, color='grey', size=10)
maximum = math.ceil(df.loc['r'].max())
minimum = 0.0
ticks = np.linspace(minimum, maximum, 3)
plt.yticks(ticks, labels=[str(tick) for tick in ticks], color='grey', size=7)
plt.ylim(minimum, maximum)
plot_radar_chart(ax, angles, values, label='r', color='red')
ax.set_xticklabels([])
plt.title(f"En-Zh Pearson Correlation", size=11, y=1.1)
plt.legend(loc='upper right', bbox_to_anchor=(1.1, 1.1))
plt.savefig('./results/zh_en_annotation_rader_plot.png')
GPT 对此无能为力。
问题在于你对
rotation
参数的计算方式。当前,你将旋转角度设置为
angle_deg + 90
,这导致标签旋转过度。
你需要做的是:
-
计算从圆心到标签点的向量角度。
这可以通过
np.arctan2(y, x)
计算,其中(x, y)
是标签点相对于圆心的坐标。 - 将角度转换为度数。
- 将旋转角度设置为计算的角度值。
以下是如何修改代码以实现此目的:
for i, angle in enumerate(angles[:-1]):
# ... (其他代码) ...
# 计算标签点坐标
x = label_position * np.cos(angle)
y = label_position * np.sin(angle)
# 计算向量角度并转换为度数
rotation = np.degrees(np.arctan2(y, x))
# ... (使用更新后的 rotation 值绘制标签) ...
通过此更改,标签将从不同角度指向圆心,从而实现你想要的效果。
标签:python,matplotlib From: 78805281