速通matplotlib库
前言
最近在复习之前学习过的知识点,因此想到把学过的总结一下,方便后面再次复习,所以有了这个系列。
说明
由于标题写的是“速通”,因此我的想法是可以让大家看完这篇文章,可以上手matplotlib库,并且明白怎么去实现自己想要的效果。
有解释错误的地方,请大家批评指正。有任何问题,也欢迎留言询问,博主看见有空就会回。
目录结构
文章目录
- 速通matplotlib库
- 1. 作用与流程
- 1.1 作用
- 1.2 流程
- 2. 画图方法速通
- 2.1 常用参数与其值
- 2.2 各个方法与其独有参数
- 3. 其它常用方法讲解
- 3.1 创建画布
- 3.2 显示图例
- 3.3 显示图像
- 3.4 保存图像
- 4. 常用的美化图像方法
- 4.1 开启网格线
- 4.2 设置坐标轴刻度
- 4.3 设置坐标轴显示范围
- 4.4 坐标轴标题和图标题
- 4.5 添加文字
- 5. 常用的技巧(重要)
- 5.1 解决不显示中文和负号的问题
- 5.2 如何一幅图多条直线
- 5.3 如何生成子图并进行绘画
- 5.4 画三维图
- 5.5 画双三次贝塞尔面
- 6. 总结
1. 作用与流程
1.1 作用
matplotlib库,可以实现我们常见的二维图、三维图的构建,并且支持各种方法来美化所画的图。
1.2 流程
在使用这个库之前,需要进行安装,不过很简单,直接pip一下即可:
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
matplotlib库的使用,遵循一个基本流程:
1. 准备数据
2. 创建画布
3. 画图
4. 美化图像
5. 显示/保存图像
小小的例子(画一个sinx函数),演示一下上面的流程:
import numpy as np
from matplotlib import pyplot as plt
# 1. 准备数据
x = np.arange(-10,10,0.1)
y = np.sin(x)
# 2. 创建画布
plt.figure()
# 3. 画图
plt.plot(x,y,label='sin(x)')
# 4. 美化图像
plt.legend() # 显示上面的label
# 5. 显示/保存图像
plt.show()
结果如下图:
2. 画图方法速通
所谓的画图方法,即你选用什么样的图,常见的如折线图、散点图、柱状图等等。
在matplotlib中,一个很关键的点在于:许多的参数都是相同的(当然你也要自己思考这个参数在某个图中是否存在,比如折线图中的每个点可以设置形状,但是你在饼状图中肯定没有这个参数,而在散点图中肯定存在这个参数),因此你只需要记住各个方法的英文名字是什么即可。
2.1 常用参数与其值
第一个参数:颜色,参数名为color
,可以简写为c
:(几乎所有都有这个参数)
取值 | 含义 |
---|---|
b | 蓝色 |
g | 绿色 |
r | 红色 |
c | 青色 |
m | 洋红色 |
y | 黄色 |
k | 黑色 |
w | 白色 |
十六进制的RGB值 | 对应颜色 |
第二个参数:线形,参数名为linestyle
,可以简写为 ls
(折线图专用):
取值 | 含义 |
---|---|
- | 实直线 |
– | 破折线 |
: | 点虚线 |
-. | 点画线 |
第三个参数:点形状,参数名为marker
(折线图、散点图都有):
取值 | 含义 |
---|---|
. | 点形 |
o | 圆圈 |
v | 向下的三角形 |
^ | 向上的三角形 |
< | 向左的三角形 |
> | 向右的三角形 |
s | 正方形 |
p | 五边形 |
* | 星形 |
+ | +形 |
x | x形 |
| | 竖线 |
_ | 横线 |
第四个参数:点的大小,名为markersize
,简写为ms
,这个参数与上面的配合使用,其值为整数值,数值越大点越大。
第五个参数:线的宽度,名为linewidth
,简写为lw
,这个参数值也是整数值,值越大,线越宽。
第六个参数:标签名称,名为label
,这个参数几乎所有方法都有,并且很重要,其效果就是图中的图例(如下图),不过要使用该参数,需要配合plt.legend()
方法使用。
2.2 各个方法与其独有参数
包含:折线图、柱状图、条形图、饼图、散点图、直方图。
折线图
plot(x,y,**kwargs):
参数:
x : 横轴
y : 纵轴
kwargs: 其它参数
小例子:
import numpy as np
from matplotlib import pyplot as plt
# 1. 准备数据
x = np.arange(-10,10,0.1)
y = np.sin(x)
# 2. 创建画布
plt.figure()
# 3. 画图
plt.plot(x,y,label='sin(x)',c='y',marker='o',ls='--')
# 4. 美化图像
plt.legend() # 显示上面的label
# 5. 显示/保存图像
plt.show()
柱状图
bar(left,height,alpha=1,width=0.8,bottom=None,**kwargs)
参数:
left : x 轴的值
height : y 轴的值,即图形的高度
alpha : 透明度,值为:0-1
width : 柱形的宽度
bottom: 底部变量
除去这些参数外,还有:color、linewidth(边框宽度)、label、edgecolor(边框颜色)等
小例子:
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 1. 准备数据
x = ['a','b','c','d']
y = [1,2,3,4]
# 2. 生成画布
fig = plt.figure()
# 3. 画柱状图
plt.bar(x,y,alpha=0.8,width=0.3,color=['r','b','y','c'],edgecolor='k',linewidth=3)
# 4. 显示曲线
plt.show()
注意点:color参数。可以看见的是,由于我们画的图有四个,因此,color参数可以写一个值(共用颜色),也可以写四个值(分开使用颜色)。其它类似的画图方法都可以使用这个思路。
条形图
其实条形图就是柱状图翻转一下,语法也很类似:
barh(y,width,**kwargs)
小例子:
# 导包
from matplotlib import pyplot as plt
# 生成画布
fig = plt.figure()
# 准备数据
x1 = [1,3,5]
y1 = [3,8,9]
# 画图
plt.barh(y=x1,width=y1,color='g',label='A')
# 其它处理
plt.legend()
# 显示曲线
plt.show()
直方图
hist(x,bins=10,stacked=False,weights=None,histtype=u'bar',edgecolor,**kwargs):
x : n维数据或者序列
bins : 组数,其值可以是整数或者序列或者auto。其中,如果是整数,则为bins+1个组;如果是序列,如[1,2,3,4],则为[1,2),[2,3),[3,4]三组;如果是auto,则会自动计算
stacked: 是否垂直重叠,默认水平重叠
weights: 数据的权重
histtype : 绘制直方图的样式,默认是条形的。
edgecolor: 边框颜色
小例子:
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 生成画布
fig = plt.figure()
# 准备数据
mu = 100
sigma = 15
x = mu + sigma * np.random.randn(10000)
# 画图
plt.hist(x,50,facecolor='b',alpha=1,edgecolor='k')
# 显示曲线
plt.show()
饼图
pie(x,explode=None,labels=None,autopct=None,pctdistance=0.6,radius=None,**kwargs):
x : 每个扇形区域的比例,如果没有归一化会自动归一化
explode: 每个扇形区域离开中心的距离
labels: 每个扇形区域的文字说明
autopct: 设置每个扇形区域的百分比文字
pctdistance: 每个扇形区域中百分比文字的距离
radius: 扇形半径
小例子:
# 导包
from matplotlib import pyplot as plt
# 生成画布
fig = plt.figure(figsize=(10,8),dpi=80)
# 准备数据
labes = ['A_Sector','B_Sector','C_Sector','D_Sector']
nums = [25,50,15,35]
colors = ['c','m','y','g']
explode = [0.1,0.1,0.1,0.1]
# 画图
plt.pie(nums,explode=explode,labels=labes,colors=colors,autopct='%3.1f%%')
# 显示曲线
plt.show()
注意点:autopct参数的用法。为了显示%,我们需要使用%来格式化%,因此需要两个%%。
除此之外,同柱状图,当用到多个颜色时,用列表来表示。
散点图
scatter(x,y,s=None,c=None,marker=None,alpha=None,**kwargs):
x:横轴数据
y:纵轴数据
s:点的大小 === markersize
c:点的颜色 === color
marker: 点的形状
alpha:透明度
小例子:
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 生成画布
fig = plt.figure(figsize=(10,8),dpi=80)
# 准备数据
x1 = np.random.randn(10)
y1 = np.random.randn(10)
# 画图
plt.scatter(x1,y1,color='r',marker='*',s=500)
# 显示曲线
plt.show()
3. 其它常用方法讲解
上面讲解了画图的方法,下面讲解一下除去画图外常用的方法。
3.1 创建画布
方法名:plt.figure
常用参数:
参数名 | 意义 | 值 |
---|---|---|
figsize | 图像宽和高的基础大小 | (width,height) |
dpi | 不管它真实意义是什么,它的作用就是让图像真实大小变为: width * dppi,height * dpi | 整数值 |
返回值:返回图像操作对象(不过它的返回对象用的不多)。
3.2 显示图例
之前画图方法有一个重要参数,即label
,该参数显示的是图像的图例,但是需要配合一个方法使用,即:
方法名:plt.legend()
作用: 让使用了label参数的曲线显示出图例。
3.3 显示图像
方法名:plt.show()
作用:让图像显示出来,如果不使用它最后不会显示出图像的。
注意点:如果调用了该方法,那么相当于内存释放了该图像,此时再调用保存图像的方法是没有效果的。
3.4 保存图像
方法名:plt.savefig()
参数:只有一个参数,即保存的文件名,不过这个文件名必须带有路径,比如.\test.png
之类的。
注意点:该方法需要在调用显示图像方法之前使用。
4. 常用的美化图像方法
4.1 开启网格线
方法名:plt.grid()
常用参数:(其实一般都直接默认参数即可)
ls :网格的线形
lw : 线宽,如:0.8
color :颜色
小例子:(上面的散点图为例)
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 生成画布
fig = plt.figure(figsize=(10,8),dpi=80)
# 准备数据
x1 = np.random.randn(10)
y1 = np.random.randn(10)
# 画图
plt.scatter(x1,y1,color='r',marker='*',s=500)
plt.grid()
# 显示曲线
plt.show()
4.2 设置坐标轴刻度
方法名:plt.xticks() or plt.yticks()
常用参数: 显示的坐标刻度范围,接受列表/ndarray参数,比如plt.xticks(np.arange(-10,10))
。
举个例子:
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 生成画布
fig = plt.figure(figsize=(10,8),dpi=80)
# 准备数据
x1 = np.random.randn(10)
y1 = np.random.randn(10)
# 画图
plt.scatter(x1,y1,color='r',marker='*',s=500)
# 坐标值刻度
plt.xticks(np.arange(-10,10))
plt.yticks(np.arange(-10,10))
# 显示网格
plt.grid()
# 显示曲线
plt.show()
4.3 设置坐标轴显示范围
这个与上面是不同的,这里设置的是坐标轴可以显示的范围,而上面设置的是坐标轴总的刻度范围,即如果刻度范围超过显示范围,会被截断。
方法名:plt.ylim() or plt.xlim()
常用参数:显示的范围,一般接受一个列表或元组,其包含两个值,即显示范围最小值和最大值。
举个例子:
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 生成画布
fig = plt.figure(figsize=(10,8),dpi=80)
# 准备数据
x1 = np.random.randn(10)
y1 = np.random.randn(10)
# 画图
plt.scatter(x1,y1,color='r',marker='*',s=500)
# 坐标值刻度
plt.xticks(np.arange(-10,10))
plt.yticks(np.arange(-10,10))
# 坐标轴显示范围
plt.xlim((-5,5))
plt.ylim((-5,5))
# 显示网格
plt.grid()
# 显示曲线
plt.show()
上面就是刻度范围超过显示范围
了,因此被截断了。
4.4 坐标轴标题和图标题
方法名:plt.xlabel() or plt.ylabel() or plt.title()
参数:都是各个标题的内容,字符串值。
举个例子:
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 生成画布
fig = plt.figure(figsize=(10,8),dpi=80)
# 准备数据
x1 = np.random.randn(10)
y1 = np.random.randn(10)
# 画图
plt.scatter(x1,y1,color='r',marker='*',s=500)
# 各个标题
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.title('the title of figure')
# 坐标值刻度
plt.xticks(np.arange(-5,5))
plt.yticks(np.arange(-5,5))
# 坐标轴显示范围
plt.xlim((-5,5))
plt.ylim((-5,5))
# 显示网格
plt.grid()
# 显示曲线
plt.show()
4.5 添加文字
方法名:plt.text()
常用参数:
参数名 | 意义 |
---|---|
x | 文字左下角x坐标 |
y | 文字左下角y坐标 |
s | 文字内容,为字符串 |
看例子:
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 生成画布
fig = plt.figure(figsize=(10,8),dpi=80)
# 准备数据
x1 = np.random.randn(10)
y1 = np.random.randn(10)
# 画图
plt.scatter(x1,y1,color='r',marker='*',s=500)
# 各个标题
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.title('the title of figure')
# 坐标值刻度
plt.xticks(np.arange(-5,5))
plt.yticks(np.arange(-5,5))
# 坐标轴显示范围
plt.xlim((-5,5))
plt.ylim((-5,5))
# 文字显示
plt.text(1,3,'hello')
# 显示网格
plt.grid()
# 显示曲线
plt.show()
可以发现一个事情:这里参数中的x、y坐标与图中的x、y坐标是对应的,那么也方便我们确定了所填写文本的位置。
5. 常用的技巧(重要)
5.1 解决不显示中文和负号的问题
由于一些众所周知的原因,matplotlib库不直接支持中文以及负号的显示,因此需要特别进行处理,这里大家不用管原理,用到的时候直接拷贝过去用即可:
# 处理中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
# 处理负号显示问题
plt.rcParams['axes.unicode_minus'] = False
5.2 如何一幅图多条直线
这一点非常简单,只需要在同一个代码中多次调用画图方法即可,举个例子:
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 生成画布
fig = plt.figure(figsize=(10,8),dpi=80)
# 准备数据
a = np.random.random((9,3))*2 # 区间 (0,2)
y1 = a[0:,1]
y2 = a[0:,2]
x = np.arange(1,10)
width = 10
height = 3
plt.xlim(-0.5,width+0.2)
plt.ylim(-0.5,height+0.2)
# 画折线
plt.plot(x,y1,linestyle='-',linewidth=1.5,color='k',marker='>')
plt.plot(x,y2,linestyle='-',linewidth=1.5,color='r',marker='*')
# 显示曲线
plt.show()
5.3 如何生成子图并进行绘画
其效果图如下:
那么,首先我们需要讲解一个新方法:
新方法
fig,ax = plt.subplots(nrows=num1,ncols=num2)
参数:
nrows: 行的个数
ncols : 列的个数
(总的画纸个数为: 行*列,但是同时注意1行2列与2行1列是不同的,虽然它们的画纸都是两个)
返回值:
ax : 返回的操作画纸的对象,可以使用ax[x,x]或者ax[x][x]的方式去索引获取目标画纸
有了上述新方法和其使用方法后,可以简单的实现一下:
# 导包
from matplotlib import pyplot as plt
import numpy as np
# 生成画布
plt.figure(figsize=(10,8),dpi=80)
fig,ax = plt.subplots(nrows=2,ncols=2)
# 处理中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
# 处理负号显示问题
plt.rcParams['axes.unicode_minus'] = False
# 准备数据
x = np.linspace(0,5,100)
y = np.cos(x)
# 画图
ax[0,0].plot(x,y)
ax[0,1].plot(x,y)
ax[1][0].plot(x,y)
ax[1][1].plot(x,y)
# 显示曲线
plt.show()
注意事项:
令人悲伤的事情,当我们操作的对象变为了ax后,有些原本的方法名字改变了,比如调整刻度范围,原来是xticks,现在变为了set_xticks。你也许会觉得不就是在原来的方法上加上了set_嘛,其实不全是,但是这是一个好的思路。
综上,如果你在操作ax,记得方法名会改变(画图的函数名字不会改变),大多数是加上set_,但是仍然有少数不是。
5.4 画三维图
matplotlib当然也支持三维图的绘画,只是相比于二维图,三维图麻烦很多,主要是数据上准备的麻烦,方法到很简单。
方法
线框图:
axes.plot_wireframe(x,y,z)
x : x轴的数据
y : y轴的数据
z : z轴的数据
axes : 可以3d显示的对象
其中,axes对象获取的方法如下(必须设置的):
# 设置画布
plt.figure(figsize=(10,8),dpi=80),
# 设置画纸,并设置成三维显示模式
axes = plt.axes(projection='3d')
另外,还支持画面,而不是线框,参数同上,只是方法名变为了plot_surface(x,y,z)
举个例子
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import axes3d
# 设置画布
plt.figure(figsize=(10,8),dpi=80),
# 设置画纸,并设置成三维显示模式
axes = plt.axes(projection='3d')
# 准备数据
r = np.linspace(0,1.25,50)
p = np.linspace(0,2*np.pi,50)
# 映射
R ,P = np.meshgrid(r,p)
# 继续生成数据
Z = ((R**2-1)**2)
X , Y = R * np.cos(P) , R * np.sin(P)
axes.plot_surface(X,Y,Z)
plt.show()
其实麻烦的就是数据的准备。
5.5 画双三次贝塞尔面
这个是我自己在上课时实现的一个案例,其实主要是如何根据公式生成数据,这里肯定只有对双三次贝塞尔曲面感兴趣的才会看,所以我就不贴公式了:
# author: baiCai
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import axes3d
# 设置画布
plt.figure(figsize=(10,8),dpi=80),
# 设置画纸,并设置成三维显示模式
axes = plt.axes(projection='3d')
# 控制点
Px = np.array([
[0,2,4,6],
[0,2,4,6],
[0,2,4,6],
[0,2,4,6]
])
Py = np.array([
[6,6,6,6],
[4,4,4,4],
[2,2,2,2],
[0,0,0,0]
])
Pz = np.array([
[0,1,1,0],
[0.5,1.5,1.5,0.5],
[0.5,1.5,1.5,0.5],
[0,1,1,0]
])
# 定义u\v
U = np.arange(0,1,0.01)
V = np.arange(0,1,0.01)
[u,v]= np.meshgrid(U,V)
# 长度
d=len(u)
Bu0 = (1 - u)**3
Bu1 = 3 * u * ((1 - u)**2)
Bu2 = 3 * (u**2) * (1 - u)
Bu3 = u**3
Bv0 = (1 - v)**3
Bv1 = 3 * v * ((1 - v)**2)
Bv2 = 3 * (v**2) * (1 - v)
Bv3 = v**3
Bu = np.concatenate((Bu0,Bu1,Bu2,Bu3),axis=0)
Bv = np.concatenate((Bv0,Bv1,Bv2,Bv3),axis=0)
# 初始化X、Y、Z
X=np.zeros(d)
Y=np.zeros(d)
Z=np.zeros(d)
# 开始计算
for i in range(0,4):
for j in range(0,4):
nj = d*j
ni = d*i
X = X + Px[i,j] * Bu[nj:nj+(d-1),:] * Bv[ni:ni+(d-1),:]
Y = Y + Py[i,j] * Bu[nj:nj+(d-1),:] * Bv[ni:ni+(d-1),:]
Z = Z + Pz[i,j] * Bu[nj:nj+(d-1),:] * Bv[ni:ni+(d-1),:]
axes.plot_surface(X,Y,Z)
plt.show()
6. 总结
上面简单介绍了matplotlib这个库的使用方法,更加深入的技巧就需要根据自己的需求去网上查找源码了。