Python实现雷达图:不同指标对应不同单位量度绘制
Python绘制雷达图:实现不同指标对应不同单位量度
解决的问题场景
当我们需要将统计数据进行可视化时,雷达图是一个很好的选择,但是传统的雷达图也容易存在一个比较严重的问题,就是对于不同指标它的单位刻度都是一样的,如果每个指标的统计数据范围差别不大,那可视化出来问题不大,就像图1中的传统雷达图一样,每个科目对应的成绩范围都在0-10之间,所以可以用雷达图比较好的表现出来,能够清晰的进行比较和分析。
图1 传统雷达图(数据范围大致相同)
但是如果每个指标对应统计数据范围差别很大,那使用单位刻度相同的雷达图表示出来就会很影响感官,几乎失去了比较分析的功能。
举个例子,如果我们要可视化这样一组数据:
指标 | A | B |
---|---|---|
1 | 4.58 | 7.03 |
2 | 7.52 | 7.60 |
3 | 51.20 | 54.27 |
4 | 49.67 | 60.60 |
5 | 19.72 | 13.34 |
很显然,这五组数据的范围差别很大,如果继续用传统的单位刻度一样的雷达图画出来会很混乱,所以要解决这个问题,通常有两种方法,一种是将所有统计数据归一化,把它们都限定在0-1的范围内,再用传统的雷达图绘制。
第二种,就是今天要介绍的不同单位量度的雷达图。
效果图
先直接上效果图,用的数据就是上面的那五组数据,只是标签名字换了一下而已。
通过图片可以清晰地看到1-5对应的五个指标的单位量度都不同,都调整了合适的起点、终点和亮度,这样就可以清晰的比较两组数据的折线图了。
上代码
import numpy as np
import matplotlib.pyplot as plt
class Radar(object):
def __init__(self, figure, title, labels,epoch,rect=None):
if rect is None:
rect = [0.05, 0.05, 0.9, 0.9]
self.n = len(title)
self.angles = np.arange(0, 360, 360.0/self.n)
self.axes = [figure.add_axes(rect, projection='polar', label='axes%d' % i) for i in range(self.n)]
self.ax = self.axes[0]
self.ax.set_thetagrids(self.angles, labels=title, fontsize=14)
for ax in self.axes[1:]:
ax.patch.set_visible(False)
ax.grid(False)
ax.xaxis.set_visible(False)
for ax,angle,label,i in zip(self.axes,self.angles,labels,epoch):
ax.set_rgrids(i[1:],angle=angle,labels=label) #这里的range(1,6)应该是对应标签的个数
ax.spines['polar'].set_visible(False)
ax.set_ylim(i[0],i[7]) #这里应该是对应轴的刻度
def plot(self,values,*args,**kw):
angle = np.deg2rad(np.r_[self.angles,self.angles[0]])
limits = []
# 把value的值进行一个换算
limits.append(values[1]-5)
limits.append(values[2]-50)
limits.append((values[3]-45)/5)
limits.append((values[4]+15)/10)
values[1] = (limits[0])*0.5+4.5
values[2] = (limits[1])*0.5+4.5
values[3] = (limits[2])*0.5+4.5
values[4] = (limits[3])*0.5+4.5
values = np.r_[values,values[0]]
self.ax.plot(angle,values,*args,**kw)
if __name__ =='__main__':
fig = plt.figure(figsize=(8,8))
#tit = list(('人均GDP/万元','年均GDP增速','第三产业占比','城镇化率','碳排放强度下降幅度'))
tit = [1,2,3,4,5]
lab = [
list(('4.5','5.0','5.5','6.0','6.5','7.0','7.5')),
list(('5','6','7','8','9','10','11')),
list(('50','51','52','53','54','55','56')),
list(('45','50','55','60','65','70','75')),
list(('-15','-5','5','15','25','35','45')),
]
epo = [
[4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5],
[4,5,6,7,8,9,10,11],
[49,50,51,52,53,54,55,56],
[40,45,50,55,60,65,70,75],
[-25,-15,-5,5,15,25,35,45]
]
plt.rcParams['font.sans-serif'] = ['SimHei']
radar = Radar(fig,tit,lab,epo)
#radar.plot([4.5,5,50,45,-15],'-', lw=2, color='r', alpha=0.4, label='全国平均') #范例
#绘制图3
radar.plot([4.58,7.52,51.20,49.67,19.72], '-', lw=2, color='r',alpha=0.4, label='A')
radar.plot([7.03,7.60,54.27,60.60,13.34], '-', lw=2, color='b', alpha=0.4, label='B')
radar.ax.legend()
plt.savefig('fig-3.png',dpi=300)
作者:T.S.G