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
defradar_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 /2defdraw_poly_patch(self):
verts = unit_poly_verts(theta)return plt.Polygon(verts, closed=True, edgecolor='k')defdraw_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 notin patch_dict:raise ValueError('unknown value for `frame`: %s'% frame)classRadarAxes(PolarAxes):
name ='radar'# use 1 line segment to connect specified points
RESOLUTION =1# define draw_frame method
draw_patch = patch_dict[frame]deffill(self,*args,**kwargs):"""Override fill so that line is closed by default"""
closed = kwargs.pop('closed',True)returnsuper(RadarAxes, self).fill(closed=closed,*args,**kwargs)defplot(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-upif x[0]!= x[-1]:
x = np.concatenate((x,[x[0]]))
y = np.concatenate((y,[y[0]]))
line.set_data(x, y)defset_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
defunit_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
defexample_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 inenumerate(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()