Matplotlib雷达图标签旋转问题:如何让标签指向圆心?
Matplotlib雷达图标签指向圆心的旋转修正方案
我尝试用Matplotlib绘制雷达图,希望每个标签从对应角度指向圆心,但当前代码实现的标签旋转效果不符合预期。以下是我的代码:
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')
问题根源
原代码的旋转角度计算未考虑极坐标的偏移(theta_offset)和方向(theta_direction)设置,导致标签旋转方向错误,无法指向圆心。
修正后的代码
修改标签绘制的循环部分即可解决问题,完整代码如下:
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]): rot_angle = np.degrees(angle) # 左半部分标签翻转180度,避免文本倒置 if angle > np.pi: rot_angle += 180 # 调整角度使标签垂直于径向线并指向圆心 rot_angle -= 90 label_position = 1.1 ax.text(angle, label_position, labels[i], ha='center', va='center', rotation=rot_angle, 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')
关键修改点
- 旋转角度计算:
- 将弧度转换为度数后,对左半部分(角度大于
np.pi)的标签额外增加180度,避免文本倒置 - 减去90度,让文本垂直于径向线,确保标签朝向圆心
- 将弧度转换为度数后,对左半部分(角度大于
- 移除不必要的transform:删除
transform=ax.transData,极坐标下直接使用rotation参数即可正确应用旋转
内容的提问来源于stack exchange,提问作者Bo Peng
相关产品推荐
相关产品推荐

