python-科研绘图系列(3)-雷达图

1. 前置文件-radar1

mport numpy as np

import matplotlib.pyplot as plt
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, frame='circle'):
    """Create a radar chart with `num_vars` axes.
    This function creates a RadarAxes projection and registers it.
    Parameters
    ----------
    num_vars : int
        Number of variables for radar chart.
    frame : {'circle' | 'polygon'}
        Shape of frame surrounding axes.
    """
    # calculate evenly-spaced axis angles
    theta = np.linspace(0, 2 * np.pi, num_vars, endpoint=False)
    # rotate theta such that the first axis is at the top
    theta += np.pi / 2

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

    def draw_circle_patch(self):
        # unit circle centered on (0.5, 0.5)
        return plt.Circle((0.5, 0.5), 0.5)

    patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch}
    if frame not in patch_dict:
        raise ValueError('unknown value for `frame`: %s' % frame)

    class RadarAxes(PolarAxes):

        name = 'radar'
        # use 1 line segment to connect specified points
        RESOLUTION = 1
        # define draw_frame method
        draw_patch = patch_dict[frame]

        def fill(self, *args, **kwargs):
            """Override fill so that line is closed by default"""
            closed = kwargs.pop('closed', True)
            return super(RadarAxes, self).fill(closed=closed, *args, **kwargs)

        def plot(self, *args, **kwargs):
            """Override plot so that line is closed by default"""
            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(np.degrees(theta), labels)

        def _gen_axes_patch(self):
            return self.draw_patch()

        def _gen_axes_spines(self):
            if frame == 'circle':
                return PolarAxes._gen_axes_spines(self)
            # The following is a hack to get the spines (i.e. the axes frame)
            # to draw correctly for a polygon frame.

            # spine_type must be 'left', 'right', 'top', 'bottom', or `circle`.
            spine_type = 'circle'
            verts = unit_poly_verts(theta)
            # close off polygon by repeating first vertex
            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 unit_poly_verts(theta):
    """Return vertices of polygon for subplot axes.
    This polygon is circumscribed by a unit circle centered at (0.5, 0.5)
    """
    x0, y0, r = [0.5] * 3
    verts = [(r * np.cos(t) + x0, r * np.sin(t) + y0) for t in theta]
    return verts


def example_data():
    # The following data is from the Denver Aero

    data1 = [
        ['ZL', 'ZR', 'ZF', 'ZM', 'ZC'],
        ('R',
         [[0.063, -0.0040000000000000001, -0.22600000000000001, -0.22900000000000001, 2.1949999999999998],
          [1.161, -0.377, -0.086999999999999994, -0.095000000000000001, -0.159],
          [0.48299999999999998, -0.79900000000000004, 2.4830000000000001, 2.4249999999999998, 0.308],
          [-0.314, 1.6859999999999999, -0.57399999999999995, -0.53700000000000003, -0.17299999999999999],
          [-0.69999999999999996, -0.41499999999999998, -0.161, -0.161, -0.253]]
         )
    ]
    return data1

2. 主程序

import numpy as np
import matplotlib.pyplot as plt
from radar1 import radar_factory
import pandas as pd

#####载入数据
data=pd.read_excel('XXXX')
V=np.array(data)
V=np.array(V)


v1 =V[:,0]
v2 =V[:,1]
v3 = V[:,2]
v4 = V[:,3]
v5 = V[:,4]
v6 =V[:,5]

############设置刻度名称
labs = ['A','B','C','D','E','F']
# 进行归一处里
Y = np.vstack((v1,v2,v3,v4,v5,v6))

N = len(labs)#种类
r = np.arange(N)

theta = np.linspace(0, 360, N, endpoint=False)#角度


# 调整角度使得正中在垂直线上
adj_angle = theta[-1] + 90 - 360
theta += adj_angle

# 将角度转化为单位弧度
X_ticks = np.radians(theta) # x轴标签所在的位置

# 首尾相连
X = np.append(X_ticks,X_ticks[0])
Y = np.hstack((Y, Y[:,0].reshape(6,1)))

# 调用Radar图函数
N = len(labs)
theta = radar_factory(N, frame='polygon')


fig, ax = plt.subplots(figsize=(15, 15),
                             subplot_kw=dict(projection='radar'))
# 画图
print(plt.ylim(0.4,1.0))
ax.plot(X, Y[0], marker='o',markersize=8,linewidth=3,alpha=0.3,label='X')
ax.plot(X, Y[1], marker='o',markersize=8,linewidth=3,alpha=0.3,label='XX')
ax.plot(X, Y[2], marker='o',markersize=8,linewidth=3,alpha=0.3,label='XXX')
ax.plot(X, Y[3], marker='o',markersize=8,linewidth=3,alpha=0.3,label='XXXX')
ax.plot(X, Y[4], marker='o',markersize=8,linewidth=3,alpha=0.3,label='XXXXX')
ax.plot(X, Y[5], marker='o',markersize=8,linewidth=3,label='XXXXXXX')


ax.set_xticks(X)#设置外围坐标


# # # 设置背景坐标系

ax.spines['polar'].set_visible(False)
#

ax.grid(axis='x') # 只有y轴设置grid
ax.grid(axis='y') # 只有y轴设置grid

ax.set_xticklabels(labs, fontproperties="SimSun", fontsize = 20) # 设置外围轴标签

ax.set_yticklabels(['50.00%','60.00%','70.00%','80.00%','90.00%','100.00%'],fontsize=20, fontproperties="SimSun")

# # # 设置X轴的grid
n_grids = np.linspace(0.1,1.1, 10, endpoint=False) # grid的网格数

grids = [[i] * (len(X)) for i in n_grids] #grids的半径

for i, grid in enumerate(grids): # 给grid 填充间隔色
    ax.plot(X, grid, color='grey', linewidth=1.5,linestyle='--',alpha=0.5)
#     # if (i>0) & (i % 2 == 0):
#     #     ax.fill_between(X, grids[i], grids[i-1], color='grey', alpha=0.1)
# plt.legend(ncol=6,fontsize=16,bbox_to_anchor=(1, -0.05))#正下
plt.legend(ncol=6,fontsize=16,bbox_to_anchor=(1, 1.1))#正上
plt.show()

3.可视化结果

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值