Matplotlib 雷达图

Matplotlib 雷达图函数

雷达图,也叫做 “极坐标图” 或 “蜘蛛网图”,它是一种用于表现多维(4 维以上)数据的图表(如下图)。对于雷达图来说,它起始于同一个圆心点,结束于最外围边缘。其中,每个坐标点代表一个指标。

雷达图

在 Matplotlib 中,我们可以使用 polar() 函数来绘制一个雷达图。

语法:

plt.polar(theta, r)

说明:

第 1 个参数 theta 表示数据点所在射线与极轴的夹角。需要注意的是,所有的角度都应该使用 “弧度” 为单位,例如 180° 就应该写成 np.pi,而 360° 就应该写成 np.pi * 2,以此类推。

在实际开发中,我们更推荐使用这种写法:度数 * np.pi / 180。这种写法可以让我们一眼就能看出角度是多少,例如下面这 2 个。

120 * np.pi / 180    # 120° 
150 * np.pi / 180    # 150°

第 2 个参数 r 是数据点到原点的距离,一般它对应实际的数据。

示例 1:画出一个点

import numpy as np
import matplotlib.pyplot as plt

# 绘图
plt.polar(45*np.pi/180, 40, marker='o', color='red')

# 刻度范围
plt.ylim(0, 100)

# 显示
plt.show()

运行之后,效果如下图所示。

Matplotlib雷达图画一个点

分析:

想要绘制一个雷达图,我们首先要学会如何在一个极坐标中绘制一个点出来。在这个例子中,plt.polar(45*np.pi/180, 40, marker='o', color='red') 表示绘制的点所处夹角为 45°,距离原点为 20,外观是一个实心圆,颜色为红色。

对于雷达图来说,我们一般都不会使用默认刻度,而需要使用 ylim() 函数来调整刻度范围。如果使用默认刻度,比如删除 plt.ylim(0, 100) 这一句代码,效果如下图所示,此时效果就不是很理想了。

Matplotlib雷达图默认刻度范围

示例 2:画出雷达图

import numpy as np
import matplotlib.pyplot as plt

# 绘图
theta = np.array([45, 135, 180, 270, 45]) * np.pi / 180
r = [20, 60, 40, 80, 20]
plt.polar(theta, r, marker='o', color='red')

# 刻度范围
plt.ylim(0, 100)

# 显示
plt.show()

运行之后,效果如下图所示。

Matplotlib绘制雷达图

分析:

想要绘制一个雷达图,我们需要确定多个点的坐标,然后将所有点连接起来。由于雷达图是一个封闭图形,它的第一个点和最后一个点要求是相同的。所以 这里可以看到 theta 的第一个元素和最后一个元素是相同的,并且 r 的第一个元素和最后一个元素是相同的。

需要注意的是,np.pi 是一个浮点数,而列表是无法和一个浮点数进行相乘的。所以我们应该先使用 np.array()(这是一个 NumPy 函数)将列表转换为数组,然后再和浮点数进行相乘。

# 正确方式
theta = np.array([45, 135, 180, 270, 45]) * np.pi / 180

# 错误方式
theta = [45, 135, 180, 270, 45] * np.pi / 180

此外需要说明的是,雷达图中每一个点的坐标是由 “角度” 和 “距离” 这两个来确定的。小伙伴们联想一下极坐标系中一个点是如何确定的就知道了。

Matplotlib 雷达图样式

在实际开发中,为了达到更好的用户体验,我们还需要对雷达图进行各种自定义,主要包括 2 个方面:① 刻度标签;② 填充颜色。

1. 刻度标签

有些情况下,雷达图默认的刻度标签并不能满足我们的开发需求。在 Matplotlib 中,我们可以使用 thetagrids() 函数来定义雷达图的刻度标签。

语法:

plt.thetagrids(angles, labels)

说明:

angles 和 labels 都是列表。ticks 是必选参数,表示 “刻度所在的角度”。labels 是可选参数,表示 “标签值”。其中 labels 是与 angles 一一对应的。

示例 3:雷达图刻度标签

import numpy as np
import matplotlib.pyplot as plt

# 绘图
plt.polar(60*np.pi/180, 40, marker='o', color='red')

# 刻度范围
plt.ylim(0, 100)
# 刻度标签
angles = [0, 60, 120, 180, 240, 300]
plt.thetagrids(angles)

# 显示
plt.show()

运行之后,效果如下图所示。

Matplotlib改变雷达图刻度标签

分析:

默认情况下,雷达图的刻度标签为:0°、45°、90°、135°、180°、225°、270°、315°。在这个例子中,我们将其刻度标签重新定义为:0°、60°、120°、180°、240°、300°。

示例 4:定义 labels

import numpy as np
import matplotlib.pyplot as plt

# 设置
plt.rcParams['font.family'] = ['SimHei', 'PingFang SC'] 
plt.rcParams['axes.unicode_minus'] = False

# 绘图
plt.polar(60*np.pi/180, 40, marker='o', color='red')

# 刻度范围
plt.ylim(0, 100)
# 刻度标签
angles = [0, 60, 120, 180, 240, 300]
labels = ['力量', '敏捷', '智力', '生命', '魔法', '耐力']
plt.thetagrids(angles, labels)

# 显示
plt.show()

运行之后,效果如下图所示。

Matplotlib雷达图定义labels

分析:

对于 plt.thetagrids(angles, labels) 函数来说,如果想要使用第 2 个参数,那么 angles 和 labels 这 2 个列表的元素个数必须相同,然后 labels 的元素会一一替换到 angles 的刻度上去。

2. 填充颜色

在 Matplotlib 中,我们可以使用 fill() 这个函数来对一个雷达图进行填充颜色。

语法:

plt.fill(theta, r, color, alpha)

说明:

fill() 函数和 polar() 函数的前 2 个参数是一样的,theta 保存的是所有点的偏移角度,r 保存的是所有点离原点的距离。

参数 color 用于定义填充的颜色,参数 alpha 用于定义透明度(0.0 ~ 1.0)。

示例 5:填充颜色

import numpy as np
import matplotlib.pyplot as plt

# 绘图
theta = np.array([45, 135, 180, 270, 45]) * np.pi / 180
r = [20, 60, 40, 80, 20]
plt.polar(theta, r, marker='o', color='red')

# 刻度范围
plt.ylim(0, 100)
# 填充颜色
plt.fill(theta, r, color='red', alpha=0.5)

# 显示
plt.show()

运行之后,效果如下图所示。

Matplotlib雷达图填充颜色

分析:

细心的小伙伴可能发现了,在上面的列表中,我们第一个点的数据是 (45, 20),而列表最后的一个数据也是 (45, 20)。

这是因为,极坐标图默认只是把点用线连起来,如果不把第一个点的数据追加到列表的最后,画出来的图形将是“缺一个口子”的。为了让雷达图形成一个封闭的多边形(首尾相连),我们必须手动将第一个数据点复制一份放到列表的最后。

Matplotlib 雷达图案例

相信大多数小伙伴都玩过游戏,对于一个英雄来说,它主要的能力指标有 6 个:力量、敏捷、智力、生命、魔法、耐力。接下来,我们尝试使用雷达图来直观地展示一个英雄的能力是怎样的。

示例 6:Matplotlib 雷达图的应用

import numpy as np
import matplotlib.pyplot as plt

# 设置
plt.rcParams['font.family'] = ['SimHei', 'PingFang SC'] 
plt.rcParams['axes.unicode_minus'] = False

# 绘图
theta = np.array([0, 60, 120, 180, 240, 300, 0]) * np.pi / 180
r = [9, 6, 3, 9, 3, 8, 9]
plt.polar(theta, r, marker='o', color='red')

# 刻度范围
plt.ylim(0, 10)
# 刻度标签
angles = [0, 60, 120, 180, 240, 300]
labels = ['力量', '敏捷', '智力', '生命', '魔法', '耐力']
plt.thetagrids(angles, labels)
# 填充颜色
plt.fill(theta, r, color='red', alpha=0.5)

# 显示
plt.show()

运行之后,效果如下图所示。

Matplotlib雷达图的实际应用

分析:

从雷达图可以很直观地看出来,这个英雄其实是一个典型的战士型英雄。相信很多小伙伴都知道 “国乒一哥” 马龙被日本媒体称之为 “六边形战士”,如果用雷达图来表示,应该是下图这样的。

六边形战士的“雷达图”

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号