速通matplotlib库

速通matplotlib库

前言

​ 最近在复习之前学习过的知识点,因此想到把学过的总结一下,方便后面再次复习,所以有了这个系列。

说明

​ 由于标题写的是“速通”,因此我的想法是可以让大家看完这篇文章,可以上手matplotlib库,并且明白怎么去实现自己想要的效果。
​ 有解释错误的地方,请大家批评指正。有任何问题,也欢迎留言询问,博主看见有空就会回。

目录结构


在这里插入图片描述

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 : 列的个数
		(总的画纸个数为:  行*列,但是同时注意12列与21列是不同的,虽然它们的画纸都是两个)
	返回值:
		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这个库的使用方法,更加深入的技巧就需要根据自己的需求去网上查找源码了。

猜你喜欢

转载自blog.csdn.net/weixin_46676835/article/details/131709664