Python matplotlib绘制雷达图

Python 碎片

共 4345字,需浏览 9分钟

 ·

2021-01-07 19:03



本篇文章介绍使用matplotlib绘制雷达图。


雷达图也被称为网络图,蜘蛛图,星图,蜘蛛网图,是一个不规则的多边形。雷达图可以形象地展示相同事物的多维指标,应用场景非常多。


一、matplotlib绘制圆形雷达图


# coding=utf-8import numpy as npimport matplotlib.pyplot as plt

results = [{"大学英语": 87, "高等数学": 79, "体育": 95, "计算机基础": 92, "程序设计": 85}, {"大学英语": 80, "高等数学": 90, "体育": 91, "计算机基础": 85, "程序设计": 88}]data_length = len(results[0])# 将极坐标根据数据长度进行等分angles = np.linspace(0, 2*np.pi, data_length, endpoint=False)labels = [key for key in results[0].keys()]score = [[v for v in result.values()] for result in results]# 使雷达图数据封闭score_a = np.concatenate((score[0], [score[0][0]]))score_b = np.concatenate((score[1], [score[1][0]]))angles = np.concatenate((angles, [angles[0]]))labels = np.concatenate((labels, [labels[0]]))# 设置图形的大小fig = plt.figure(figsize=(8, 6), dpi=100)# 新建一个子图ax = plt.subplot(111, polar=True)# 绘制雷达图ax.plot(angles, score_a, color='g')ax.plot(angles, score_b, color='b')# 设置雷达图中每一项的标签显示ax.set_thetagrids(angles*180/np.pi, labels)# 设置雷达图的0度起始位置ax.set_theta_zero_location('N')# 设置雷达图的坐标刻度范围ax.set_rlim(0, 100)# 设置雷达图的坐标值显示角度,相对于起始角度的偏移量ax.set_rlabel_position(270)ax.set_title("计算机专业大一(上)")plt.legend(["弓长张", "口天吴"], loc='best')plt.show()


运行结果:



绘制雷达图需要先建立极坐标系,关于极坐标系可以自己了解一下。建立好极坐标系后可以在极坐标系中绘制折线图、柱状图等,大部分情况,都是用折线图,形成一个不规则的闭合多边形。本文中用某高校大一的期末考试成绩作为例子来演示雷达图的效果。


linspace(): 用于将极坐标系根据数据的维度进行等分,linspace()函数的第一个参数传入起始角度,第二参数传入结束角度,第三个参数传入分成多少等份。其他参数根据需要传入,如endpoint默认为True,最后一个数据处于结束的角度,根据本例中前面的参数0~2π,应该设置为False,否则最后一个数据与第一个数据角度重叠了。


concatenate(): 使雷达图的数据是环形封闭的,concatenate()函数的第一个参数是一个元组,元组中的每个元素是一个数组,concatenate()函数将这些数组连接到一起,组成一个新的数组。要让绘制的雷达图封闭,将数据的第一个值连接到数组的结尾即可。


本文用折线图plot()来绘制雷达图,使用figure()函数设置好图形的大小和清晰度,然后使用subplot()函数来创建一张子图。subplot()函数的第一个参数传入长度为3的数字,第一个数字表示将画布分成几行,第二个数字表示将画布分成几列,第三个数字表示当前的子图处于哪个位置(按从左至右、从上到下的顺序排序),第三个数字不能超出前两个数字切分的子图数范围。如111表示将画布分成一行一列(只有一张子图),当前的子图处于第一张子图中。在subplot()函数中,将polar参数设置成True,得到的图形才是极坐标。


极坐标系设置完成后,使用子图对象ax调用折线图函数plot(),即可绘出雷达图。如果有多组数据,多次调用plot()函数即可。


使用set_thetagrids()方法设置雷达图中每个维度的标签和显示位置。使用set_theta_zero_location()方法设置雷达图的0度位置,可以传入"N"、"NW"、"W"、"SW"、"S"、"SE"、"E"、"NE"八个方位缩写。使用set_rlim()方法设置极坐标上的刻度范围。使用set_rlabel_position()方法设置极坐标上的刻度标签显示位置,传入一个相对于雷达图0度的角度值。当然还可以根据需要设置其他属性,如标题、图例等。


在上面的例子中,将两位同学的考试成绩绘制成了雷达图,通过雷达图,可以看出两个人的单科成绩互有高低,而整体来看,两位同学的成绩都很优秀。上面的雷达图中,网格线都是圆形的,而用折线图连接的雷达图两个维度之间是直线连接的,所以将网格线换成多边形会更合理一点。


二、matplotlib绘制多边形雷达图


import numpy as npimport matplotlib.pyplot as plt

results = [{"大学英语": 87, "高等数学": 79, "体育": 95, "计算机基础": 92, "程序设计": 85}, {"大学英语": 80, "高等数学": 90, "体育": 91, "计算机基础": 85, "程序设计": 88}]data_length = len(results[0])angles = np.linspace(0, 2*np.pi, data_length, endpoint=False)labels = [key for key in results[0].keys()]score = [[v for v in result.values()] for result in results]score_a = np.concatenate((score[0], [score[0][0]]))score_b = np.concatenate((score[1], [score[1][0]]))angles = np.concatenate((angles, [angles[0]]))labels = np.concatenate((labels, [labels[0]]))fig = plt.figure(figsize=(10, 6), dpi=100)fig.suptitle("计算机专业大一(上)")ax1 = plt.subplot(121, polar=True)ax2 = plt.subplot(122, polar=True)ax, data, name = [ax1, ax2], [score_a, score_b], ["弓长张", "口天吴"]for i in range(2): for j in np.arange(0, 100+20, 20): ax[i].plot(angles, 6*[j], '-.', lw=0.5, color='black') for j in range(5): ax[i].plot([angles[j], angles[j]], [0, 100], '-.', lw=0.5, color='black') ax[i].plot(angles, data[i], color='b') # 隐藏最外圈的圆 ax[i].spines['polar'].set_visible(False) # 隐藏圆形网格线 ax[i].grid(False) for a, b in zip(angles, data[i]): ax[i].text(a, b+5, '%.00f' % b, ha='center', va='center', fontsize=12, color='b') ax[i].set_thetagrids(angles*180/np.pi, labels) ax[i].set_theta_zero_location('N') ax[i].set_rlim(0, 100) ax[i].set_rlabel_position(0) ax[i].set_title(name[i])plt.show()


运行结果:



在极坐标系中,极径值相等的点在一个圆上,所以绘制的雷达图中,网格线默认都是圆形的。如果要绘制多边形的雷达图,则需要将圆形的网格线隐藏,然后根据刻度范围绘制出多边形的网格线。


首先使用plot()函数,根据刻度范围,绘制出同心的多个多边形和多个维度方向的极轴,作为雷达图的网格线,形成一张“网”。


链式调用极坐标的spines['polar'].set_visible()方法,传入参数False,将极坐标系最外圈的圆形隐藏。调用grid()方法,传入参数False,将极坐标系中的的圆形网格线隐藏。


修改完网格线后,即可达到多边形的效果。在第二次绘制雷达图时,将两位同学的成绩分到两张不同的雷达图中,并用text()方法设置了每个维度的数据标注,使用fig对象的suptitle()方法来设置整张图形的标题。


上面的两次绘图,将两位同学的成绩绘制在同一张雷达图时,更方便对比两位同学的成绩,如比较谁更全面、更优秀。分开绘制时,更方便分析个人的成绩情况,如是否偏科。而相对于圆形的雷达图,在多边形的雷达图中,不会出现雷达图与网格线的不合理交叉(雷达图与网格线交叉两次),使用多边形网格线更合理。



浏览 13
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报