"径向网格必须严格正面"雷达图上的错误

时间:2016-07-08 09:31:04

标签: python python-2.7 matplotlib data-visualization radar-chart

虽然绘制了我的复杂雷达图,但我得到了错误"径向网格必须严格为正#34;但我在雷达图中使用的所有值和范围都是正数。有人能告诉我为什么我会收到这个错误,我能做些什么来解决它?我使用的代码如下: -

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns # improves plot aesthetics


def _invert(x, limits):
    """inverts a value x on a scale from
    limits[0] to limits[1]"""
    return limits[1] - (x - limits[0])

def _scale_data(data, ranges):
    """scales data[1:] to ranges[0],
    inverts if the scale is reversed"""
    for d, (y1, y2) in zip(data[1:], ranges[1:]):
        assert (y1 <= d <= y2) or (y2 <= d <= y1)
    x1, x2 = ranges[0]
    d = data[0]
    if x1 > x2:
        d = _invert(d, (x1, x2))
        x1, x2 = x2, x1
    sdata = [d]
    for d, (y1, y2) in zip(data[1:], ranges[1:]):
        if y1 > y2:
            d = _invert(d, (y1, y2))
            y1, y2 = y2, y1
        sdata.append((d-y1) / (y2-y1) 
                     * (x2 - x1) + x1)
    return sdata

class ComplexRadar():
    def __init__(self, fig, variables, ranges,
                 n_ordinate_levels=6):
        angles = np.arange(0, 360, 360./len(variables))

        axes = [fig.add_axes([0.1,0.1,0.8,0.8],polar=True,
                label = "axes{}".format(i)) 
                for i in range(len(variables))]
        l, text = axes[0].set_thetagrids(angles, 
                                         labels=variables)
        [txt.set_rotation(angle-90) for txt, angle 
             in zip(text, angles)]
        for ax in axes[1:]:
            ax.patch.set_visible(False)
            ax.grid("off")
            ax.xaxis.set_visible(False)
        for i, ax in enumerate(axes):
            grid = np.linspace(*ranges[i], 
                               num=n_ordinate_levels)
            gridlabel = ["{}".format(round(x,2)) 
                         for x in grid]
            if ranges[i][0] > ranges[i][1]:
                grid = grid[::-1] # hack to invert grid
                          # gridlabels aren't reversed
            gridlabel[0] = "" # clean up origin
            ax.set_rgrids(grid, labels=gridlabel,
                         angle=angles[i])
            #ax.spines["polar"].set_visible(False)
            ax.set_ylim(*ranges[i])
        # variables for plotting
        self.angle = np.deg2rad(np.r_[angles, angles[0]])
        self.ranges = ranges
        self.ax = axes[0]
    def plot(self, data, *args, **kw):
        sdata = _scale_data(data, self.ranges)
        self.ax.plot(self.angle, np.r_[sdata, sdata[0]], *args, **kw)
    def fill(self, data, *args, **kw):
        sdata = _scale_data(data, self.ranges)
        self.ax.fill(self.angle, np.r_[sdata, sdata[0]], *args, **kw)

# example data
variables = ("Attribute1", "Attribute2", "Attribute3", 
            "Attribute4", "Attribute5", "Attribute6", "Attribute7",
             "Attribute8", "Attribute9", "Attribute10", "Attribute11",
             "Attribute12", "Attribute13", "Attribute14", "Attribute15",
             "Attribute16", "Attribute17")
data = (1.0, 185, 0.02, 
        1.5, 0.1, 1.3, 1.1,
        2.3, 0.1, 6.6, 24.5,
        83, 7.5, 5.6, 4.6,
        6.5, 1.3)
data2 = (1.0, 177, 0.0,
         0.0, 0.7, 1.3, 1.3,
         4.3, 0.0, 4.7, 30,
         93, 3.7, 5.0, 7.7,
         8.0, 3.5)
ranges = [(10.0, 0.0), (170.0, 189.0), (0.0, 0.3),
         (0.6, 5.2), (0.1, 2.0), (0.3, 2.2), (1.4, 0.3),
         (0.9, 3.0), (0.0, 0.7), (2.6, 11.4), (14.4, 43.5),
         (72.0, 94.0), (1.4, 7.9), (2.5, 6.5), (2.4, 6.2),
         (4.0, 7.9), (1.1, 3.9)]            
# plotting
fig1 = plt.figure(figsize=(9, 9))
radar = ComplexRadar(fig1, variables, ranges)
radar.plot(data, color="deepskyblue", label= "Compare1")
radar.fill(data, color="deepskyblue", alpha=0.5)
radar = ComplexRadar(fig1, variables, ranges)
radar.plot(data2, color="orangered", label= "Compare2")
radar.fill(data2, color="orangered", alpha=0.5)
radar.ax.legend(loc='upper center', bbox_to_anchor=(0.9, 1.10),
      fancybox=False, shadow=False, ncol=48)
plt.show()   

1 个答案:

答案 0 :(得分:1)

嗨,这是学习一些调试技巧的好时机。在遇到类似错误时,您要做的第一件事就是将其本地化到您的代码中。幸运的是,python通过回溯为您完成此操作。这些追溯有时可能会非常令人生畏,但仔细检查就会开始变得更有意义并能提供非常有价值的信息。因此,让我们从错误的追溯开始。

追溯的前两部分是:

ValueError                                Traceback (most recent call last)
<ipython-input-454-63a43ee81b1a> in <module>()
     91 # plotting
     92 fig1 = plt.figure(figsize=(9, 9))
---> 93 radar = ComplexRadar(fig1, variables, ranges)
     94 radar.plot(data, color="deepskyblue", label= "Compare1")
     95 radar.fill(data, color="deepskyblue", alpha=0.5)

<ipython-input-454-63a43ee81b1a> in __init__(self, fig, variables, ranges, n_ordinate_levels)
     54             gridlabel[0] = "" # clean up origin
     55             ax.set_rgrids(grid, labels=gridlabel,
---> 56                          angle=angles[i])
     57             #ax.spines["polar"].set_visible(False)
     58             ax.set_ylim(*ranges[i])

因此,我们可以看到问题来自ComplexRadar ax.set_rgrids方法中的__init__。所以我们知道它将成为我们传递的参数的问题,gridangles。要获得更多想法,请查看错误消息的最后一部分:

/home/ianhi/anaconda/lib/python2.7/site-packages/matplotlib/projections/polar.pyc in set_rgrids(self, radii, labels, angle, fmt, **kwargs)
    565         rmin = radii.min()
    566         if rmin &lt;= 0:
--> 567             raise ValueError('radial grids must be strictly positive')
    568 
    569         self.set_yticks(radii)

ValueError: radial grids must be strictly positive

if rmin <= 0:所以我们得到的地方是严格肯定的#34;从。虽然你传递的径向值都不是负数,但是其中一些可能不会大于0.对于像这样的简短代码,一个简单的方法是简单地在违规行之前添加一个print语句。

print(grid)
ax.set_rgrids(grid, labels=gridlabel,
             angle=angles[i])

这样做我发现grid = [ 0. 2. 4. 6. 8. 10.]。 AhHah!这包含0.你必须选择你想从哪里开始网格。

出于测试目的,我使用grid[0]=.01的快速和脏修复只发现第二个radar.plot命令也会抛出错误!

这给了我们一个相当神秘的空白AssertionError

AssertionError                            Traceback (most recent call last)
<ipython-input-458-2a30b515f0d9> in <module>()
     96 radar.fill(data, color="deepskyblue", alpha=0.5)
     97 radar = ComplexRadar(fig1, variables, ranges)
---> 98 radar.plot(data2, color="orangered", label= "Compare2")
     99 radar.fill(data2, color="orangered", alpha=0.5)
    100 radar.ax.legend(loc='upper center', bbox_to_anchor=(0.9, 1.10),

<ipython-input-458-2a30b515f0d9> in plot(self, data, *args, **kw)
     63         self.ax = axes[0]
     64     def plot(self, data, *args, **kw):
---> 65         sdata = _scale_data(data, self.ranges)
     66         self.ax.plot(self.angle, np.r_[sdata, sdata[0]], *args, **kw)
     67     def fill(self, data, *args, **kw):

&lt;ipython-input-458-2a30b515f0d9> in _scale_data(data, ranges)
     13     inverts if the scale is reversed"""
     14     for d, (y1, y2) in zip(data[1:], ranges[1:]):
---> 15         assert (y1 <= d <= y2) or (y2 <= d <= y1)
     16     x1, x2 = ranges[0]
     17     d = data[0]

AssertionError: 

没有有用的消息描述问题的原因是你的方法_scale_data实际上是在引发这个错误。这个断言语句告诉我们d相对于y2和y1的值。相反,它实际告诉我们,我们对d的一些看法是不真实的。为了弄清楚发生了什么,让我们在try除了块:

中包围断言语句
try:
    assert (y1 <= d <= y2) or (y2 <= d <= y1)
except AssertionError:
    print(d,y1,y2)

让我们留下几个例子,其中d既不满足条件,也不满足条件:

 d     y1   y2

(0.0, 0.6, 5.2)
(4.3, 0.9, 3.0)
(7.7, 2.4, 6.2)
(8.0, 4.0, 7.9)
(0.0, 0.6, 5.2)
(4.3, 0.9, 3.0)
(7.7, 2.4, 6.2)
(8.0, 4.0, 7.9)

在ax.set_rgrids命令之前,这个尝试除了语句以及grid [0] =。001允许你的代码运行给出下面的图。但是,您应该考虑更改数据集以避免grid [0] = 0问题,并可能删除assert语句,否则如果数据失败则更正数据。希望这会有所帮助,因此您可以更轻松地下次调试。

enter image description here