【问题标题】:Add gap between label and radar chart in matplotlib在 matplotlib 中添加标签和雷达图之间的间隙
【发布时间】:2021-07-25 05:28:17
【问题描述】:

我需要一个雷达图来可视化一些关键数据。

所以我从here 获取代码并稍作更改,使其符合我的需要。

这是我用于雷达图的代码:

%matplotlib inline
import matplotlib.pyplot as plt
from math import pi

f = plt.figure(figsize=(10,5))

categories=['consistency', 'correctness', 'completeness']
N = len(categories)

values=[59,80,60]
values += values[:1]
values

angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]

ax = f.add_subplot(111, polar=True)

plt.xticks(angles[:-1], categories, color='grey', size=8)

ax.set_rlabel_position(180)
plt.yticks([20,40,60,80,100], ["20","40","60","80","100"], color="grey", size=10)
plt.ylim(0,100)

ax.plot(angles, values, 'o-', linewidth=1, linestyle='solid')

ax.fill(angles, values, 'b', alpha=0.1)

我注意到一件事,如您所见here,标签非常接近雷达图,因为它们比雷达图示例中使用的标签长。

【问题讨论】:

  • 回答问题,而不是在问题中提供解决方案。 (否则,有什么问题?)
  • @bbd108 Tanks,我在您发布的链接中找到了解决方案。

标签: python matplotlib


【解决方案1】:

我在评论部分链接的帖子中找到了解决方案。

这是修改后的代码:

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from math import pi

f = plt.figure(figsize=(8,4))

categories=['consistency', 'correctness', 'completeness']
N = len(categories)

values=[59,80,60]
values += values[:1]
values

angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]

ax = f.add_subplot(111, polar=True)

plt.xticks(angles[:-1], categories, color='grey', size=10)

for label,i in zip(ax.get_xticklabels(),range(0,len(angles))):

    angle_rad=angles[i]
    if angle_rad <= pi/2:
        ha= 'left'
        va= "bottom"

    elif pi/2 < angle_rad <= pi:
        ha= 'right'
        va= "bottom"

    elif pi < angle_rad <= (3*pi/2):
        ha= 'right'
        va= "top"  

    else:
        ha= 'right'
        va= "bottom"

    label.set_verticalalignment(va)
    label.set_horizontalalignment(ha)

ax.set_rlabel_position(180)
plt.yticks([20,40,60,80,100], ["20","40","60","80","100"], color="grey", size=10)
plt.ylim(0,100)

ax.plot(angles, values, 'o-', linewidth=1, linestyle='solid')

ax.fill(angles, values, 'b', alpha=0.1)

如您所见,here 现在标签位置正确。

【讨论】:

    【解决方案2】:

    提供的解决方案没有考虑方向和偏移。 在我的雷达图中,我的偏移量为 pi/2,因此第一个轴位于顶部(而不是右侧),方向为 -1(因此轴位于顺时针方向,而不是默认的逆时针方向)

        # If you want the first axis to be on top:
        ax.set_theta_offset(pi / 2)
        # If you want labels to go clockwise (counterclockwise is default)
        ax.set_theta_direction(direction='clockwise')
    

    无论如何,我稍微修改了您的解决方案以包含这些解决方案:

        rstep = int(ax.get_theta_direction())
        if rstep > 0:
            rmin = 0
            rmax = len(angles)
        else:
            rmin = len(angles)-1
            rmax = -1
    
        for label, i in zip(ax.get_xticklabels(), range(rmin, rmax, rstep)):
            angle_rad = angles[i] + ax.get_theta_offset()
            if angle_rad <= pi / 2:
                ha = 'left'
                va = "bottom"
            elif pi / 2 < angle_rad <= pi:
                ha = 'right'
                va = "bottom"
            elif pi < angle_rad <= (3 * pi / 2):
                ha = 'right'
                va = "top"
            else:
                ha = 'left'
                va = "top"
            label.set_verticalalignment(va)
            label.set_horizontalalignment(ha)
    

    请注意,答案中的“else:”位也有一个小错误。 ha/va 设置为右/下,它应该在左/上。 (示例图表不明显,因为它在该象限中没有标签)。

    【讨论】: