Matplotlib径向图(极坐标图) - 子轴控制

时间:2017-07-28 21:38:01

标签: python matplotlib

我有一个多边形径向图,但我无法弄清楚如何使y-tick线像图的其余部分一样多边形。

radar.py

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.path import Path
from matplotlib.spines import Spine
from matplotlib.projections.polar import PolarAxes
from matplotlib.projections import register_projection

def _radar_factory(num_vars):
    theta = 2*np.pi * np.linspace(0, 1-1./num_vars, num_vars)
    theta += np.pi/2

    def unit_poly_verts(theta):
        x0, y0, r = [0.5] * 3
        verts = [(r*np.cos(t) + x0, r*np.sin(t) + y0) for t in theta]
        return verts

    class RadarAxes(PolarAxes):
        name = 'radar'
        RESOLUTION = 1

        def fill(self, *args, **kwargs):
            closed = kwargs.pop('closed', True)
            return super(RadarAxes, self).fill(closed=closed, *args, **kwargs)

        def plot(self, *args, **kwargs):
            lines = super(RadarAxes, self).plot(*args, **kwargs)
            for line in lines:
                self._close_line(line)

        def _close_line(self, line):
            x, y = line.get_data()
            # FIXME: markers at x[0], y[0] get doubled-up
            if x[0] != x[-1]:
                x = np.concatenate((x, [x[0]]))
                y = np.concatenate((y, [y[0]]))
                line.set_data(x, y)

        def set_varlabels(self, labels):
            self.set_thetagrids(theta * 180/np.pi, labels)

        def _gen_axes_patch(self):
            verts = unit_poly_verts(theta)
            return plt.Polygon(verts, closed=True, edgecolor='k')

        def _gen_axes_spines(self):
            spine_type = 'circle'
            verts = unit_poly_verts(theta)
            verts.append(verts[0])
            path = Path(verts)
            spine = Spine(self, spine_type, path)
            spine.set_transform(self.transAxes)
            return {'polar': spine}

    register_projection(RadarAxes)
    return theta

def radar_graph(labels = [], values = []):
    N = len(labels) 
    theta = _radar_factory(N)
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1, projection='radar')
    ax.set_ylim(0,100)
    ax.set_yticks([20, 40, 60, 80, 100])
    ax.set_yticklabels(['','','','',''])
    ax.plot(theta, values, color='k', linestyle='dashed', linewidth=.2)
    ax.fill(theta, values, color='#23B5BA')
    ax.set_varlabels(labels)

    plt.savefig("radar.png", dpi=100)

以下是我如何调用radar.py来生成图表:

from radar import radar_graph

labels = ['1', '2', '3', '4', '5']
values = [65, 66, 53, 54, 78]

radar_graph(labels, values)

正如您在此图像中看到的那样,y轴是圆形,但整体结构是多边形.Radar图像:

Radar Image

也许有一种方法可以改变类似于刺的yticks。

1 个答案:

答案 0 :(得分:0)

通过ImportanceOfBeingErnest解决的问题,而不是尝试更改默认的圆子网格,我们只是隐藏它并绘制我们想要的子网格作为多边形。

我们可以将以下内容添加到Radar.py

    #Hide Circle Grid
    ax.grid(alpha=0.0)
    #Draw Sub-axis Grid
    ax.plot(theta, [.5,.5,.5,.5,.5], color='grey', linestyle='solid', linewidth=.2, alpha=1)
    ax.plot(theta, [20,20,20,20,20], color='grey', linestyle='solid', linewidth=.2, alpha=1)
    ax.plot(theta, [40,40,40,40,40], color='grey', linestyle='solid', linewidth=.2, alpha=1)
    ax.plot(theta, [60,60,60,60,60], color='grey', linestyle='solid', linewidth=.2, alpha=1)
    ax.plot(theta, [80,80,80,80,80], color='grey', linestyle='solid', linewidth=.2, alpha=1)

虽然我确信有一个更优雅的解决方案,但这有效。