上一节我们介绍了一些常见的图形绘制,接下来我们将继续绘制更多的图形,并让图形更加美观可用
文章主要针对初学者,只介绍了一些常用的参数
一、堆积面积图
堆积面积图和折线图一样,都是通过连接不同的点组成的
因此,同样只需要X,Y即可绘制图形
它的函数名为 stackplot
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [1, 2, 3, 4, 5]
y2 = [1, 2, 4, 6, 8]
y3 = [1, 3, 6, 10, 15]
plt.stackplot(x, y1, y2, y3)
plt.show()
这里我们同时将三组Y值同时输入到了一个函数中。
和其他图形一样,同样可以使用 color 来设置颜色
二、饼图和环状图
刚才只是开胃菜,饼图和环状图所需要的参数就更多了。
1.饼图
观察饼图,我们需要以下参数:数值、标签、色彩、突起版块
import matplotlib.pyplot as plt
#设置数值
sizes = [15, 30, 45, 10]
#设置标签
labels = ['Frogs', 'Hogs', 'Dogs', 'Logs']
#设置突起
explode = (0, 0.1, 0, 0)
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%')
plt.show()
其中 explode 表示的是突起的程度,我们将第二个数的突起值设为0.1,可以在图中看到第二个Hogs在板块中突起
由于饼图用于百分比显示,而不是数值显示
因此我们需要添加 autopct 参数来将数值转化为百分比
其中 autopct=‘%1.1f%%’ 中第二个1表示保留几位小数,此时我们设置的是保留一位小数
如果要保留两位小数就是
autopct=‘%1.2f%%’
2.环状图
环状图是一种特殊的饼图
绘制方法和饼图一样,只需要额外添加一个参数
import matplotlib.pyplot as plt
sizes = [151, 310, 415, 110]
labels = ['Frogs', 'Hogs', 'Dogs', 'Logs']
plt.pie(sizes, labels=labels, autopct='%1.2f%%',wedgeprops={'width':0.5})
plt.show()
在这里有一个新的参数
wedgeprops={‘width’:0.5}
只需要添加这个参数,就可以设置环状的大小,当数值越小,环状图的宽度就越小
三、雷达图
在介绍选手参数的时候,往往会采用雷达图来展示选手在各种参数上的水平。
例如在 英雄联盟 游戏中,雷达图是评估一个选手实力的体现
绘制雷达图会稍微有点难度,使用的函数为 plt.polar
import matplotlib.pyplot as plt
import numpy as np
#标签的设置
labels=np.array(['Economy', 'Health', 'Family', 'Freedom', 'Trust', 'Generosity'])
labels=np.concatenate((labels,[labels[0]]))
#数据的设置
data1 = np.random.rand(6)
data2 = np.random.rand(6)
data1 =np.concatenate((data1,[data1[0]]))
data2 =np.concatenate((data2 ,[data2[0]]))
num = 6
#角度的设置
angles = np.linspace(0, 2 * np.pi, num, endpoint=False)
angles = np.concatenate((angles,[angles[0]]))
#绘制角度和极坐标
plt.polar(angles,data1)
plt.polar(angles,data2)
plt.thetagrids(angles * 180/np.pi,labels=labels)
plt.show()
看上去不太复杂?让我们一个一个来看
对于一个雷达图有哪些组成部分,数据、标签 貌似没有了,那为什么还会有这么多代码呢?
其实,对于一个雷达图,你还需要确定数据所存在的角度。雷达图是圆的,因此如何确定不同数据的位置成为一件重要的事情。
1.角度的设置
np.linspace函数
angles = np.linspace(0, 2 * np.pi, num, endpoint=False)
angles = np.concatenate((angles,[angles[0]]))
在这个代码中,我们使用 numpy 库中的 linspace 创建一个根据 num 这个数值等分的一组数
linspace 函数会根据 区间起始、区间终点、几等分。这三个数,将区间内变成几等分
例如:
test = np.linspace(0, 9, 10)
test是10个数,从0开始到9为止
n
p
.
l
i
n
s
p
a
c
e
(
0
,
9
,
10
)
=
[
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
]
np.linspace(0, 9, 10)=[0,1,2,3,4,5,6,7,8,9]
np.linspace(0,9,10)=[0,1,2,3,4,5,6,7,8,9]
它会包括第一个数和最后一个数。
而另一个参数 endpoint=False,它会去掉最后一个值,也就是最后一位不是9。
但是此时就无法完成10个数字了,只有9个数字了。因此,这个参数实际上是分成了11份,而最后的数字9被删除,就得到了10个等分但又不包含最后一位的一组数
print(np.linspace(0, 9, 10))
print(np.linspace(0, 9, 10, endpoint=False))
print(np.linspace(0, 9, 11))
猜一下输出结果?
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
[0. 0.9 1.8 2.7 3.6 4.5 5.4 6.3 7.2 8.1]
[0. 0.9 1.8 2.7 3.6 4.5 5.4 6.3 7.2 8.1 9. ]
不知道你是否明白。
再回到角度设置的代码
angles = np.linspace(0, 2 * np.pi, num, endpoint=False)
区间起点为 0,终点为 2π,num我们设置的是6,添加了 endpoint=False 参数
也就是得到6个数但不包括2π
0
,
π
3
,
2
π
3
,
π
,
4
π
3
,
5
π
3
0,\frac{π}{3},\frac{2π}{3},π,\frac{4π}{3},\frac{5π}{3}
0,3π,32π,π,34π,35π
我们发现它刚刚好等分了一个圆
因此,可以得到一个便捷的记忆技巧。
按照传统思维,将2π进行6等分,我们会将这样做
2
π
6
=
π
3
\frac{2π}{6}=\frac{π}{3}
62π=3π
得到每一份是 π/3,有些初学者会弄混 np.linspace() 的做法,误认为默认情况下算法就是这么做的。其实
np.linspace(0, 2 * np.pi, num)
得到的结果是
0
,
2
π
5
,
4
π
5
,
6
π
5
,
8
π
5
,
2
π
0,\frac{2π}{5},\frac{4π}{5},\frac{6π}{5},\frac{8π}{5},2π
0,52π,54π,56π,58π,2π
如果想达到我们想要的,就必须加上 endpoint=False 这个参数
np.concatenate函数
我们得到了六个等分整个圆的数值后,由于雷达图需要首尾连接。
因此还需要 np.concatenate() 这个函数
angles = np.concatenate((angles,[angles[0]]))
np.concatenate() 函数会将其中的 (angles,[angles[0]]) 将他们组合成一个新的 NumPy 数组
很容易理解
a
n
g
l
e
s
=
[
0
,
π
3
,
2
π
3
,
π
,
4
π
3
,
5
π
3
]
angles=[0,\frac{π}{3},\frac{2π}{3},π,\frac{4π}{3},\frac{5π}{3}]
angles=[0,3π,32π,π,34π,35π]
那么新的angles为
a
n
g
l
e
s
=
[
0
,
π
3
,
2
π
3
,
π
,
4
π
3
,
5
π
3
,
0
]
angles=[0,\frac{π}{3},\frac{2π}{3},π,\frac{4π}{3},\frac{5π}{3},0]
angles=[0,3π,32π,π,34π,35π,0]
实现了首尾连接
2.标签和数据的设置
数据设置
同样,数据也是需要进行首尾连接的
data1 =np.concatenate((data1,[data1[0]]))
data2 =np.concatenate((data2 ,[data2[0]]))
标签设置
标签也不例外
labels=np.array(['Economy', 'Health', 'Family', 'Freedom', 'Trust', 'Generosity'])
labels=np.concatenate((labels,[labels[0]]))
但是由于 plt.polar() 函数不能直接将标签代入,因此我们需要一个新的函数来添加上标签
plt.thetagrids(angles * 180/np.pi,labels=labels)
plt.thetagrids() 用于在雷达图或极坐标图上设置角度网格和它们的标签
其中第一个参数代表着不同的角度,第二个参数代表着标签
需要注意的是,plt.thetagrids()所采用的是度数,而不是弧度
因此,还需要将弧度制转化为角度值,换算则需要乘上 180/π
3.绘制雷达图
经历了这么久,总算可以绘制一个雷达图了
plt.polar(angles,data1)
plt.polar(angles,data2)
plt.thetagrids(angles * 180/np.pi,labels=labels)
plt.show()
使用 plt.polar() 函数添加角度和数据
再使用 plt.thetagrids() 函数添加标签
一个像样的雷达图就画好了
填充雷达
plt.fill(angles, data1)
如果需要将雷达图框住的区域填充,那么就需要 plt.fill() 函数了
只需要和雷达图绘制一样,填上角度和数据就可以自动填充了
第一期在这里
【可视化1-初步认识】使用Python中matplotlib.pyplot库绘制 折线图、柱状图、散点图、直方图