matplotlib

why matplotlib?

如果您使用过“工科神器”MATLAB,您一定会惊叹于MATLAB中惊人的可视化能力,其中的函数绘图,成为了无数SCI论文中真实数据配图的来源。小小的plot函数,画出了人类先进科学进步的曲线。

python中的matplotlib库,与MATLAB中的plot函数有点像,也许这正是它名字的来源。这是一个2D绘图库,利用它可以画出许多高质量的图像。只需几行代码即可生成直方图,条形图,饼图,散点图等。Matplotlib可用于Python脚本,Python和IPython shell,Jupyter笔记本,Web应用程序服务器和四个图形用户界面工具包。

希望以下教程可以为您带来一些帮助。

安装

请查看上方anaconda教程,配置好python环境。使用命令pip install matplotlibconda install matplotlib 进行安装。使用时,直接import即可。

Matplotlib.pyplot

Matplotlib 中的 pyplot 模块是一个类似命令风格的函数集合,这使得 Matplotlib 的工作模式和 MATLAB 相似。

pyplot 模块提供了可以用来绘图的各种函数,比如创建一个画布,在画布中创建一个绘图区域,或是在绘图区域添加一些线、标签等。以下表格对这些函数做了简单地介绍。若您有MATLAB基础,看着本节即可上手使用。

绘图类型

函数名称 描述
Bar 绘制条形图
Barh 绘制水平条形图
Boxplot 绘制箱型图
Hist 绘制直方图
his2d 绘制2D直方图
Pie 绘制饼状图
Plot 在坐标轴上画线或者标记
Polar 绘制极坐标图
Scatter 绘制x与y的散点图
Stackplot 绘制堆叠图
Stem 用来绘制二维离散数据绘制(又称为“火柴图”)
Step 绘制阶梯图
Quiver 绘制一个二维按箭头

Image函数

函数名称 描述
Imread 从文件中读取图像的数据并形成数组。
Imsave 将数组另存为图像文件。
Imshow 在数轴区域内显示图像。

Axis函数

函数名称 描述
Axes 在画布(Figure)中添加轴
Text 向轴添加文本
Title 设置当前轴的标题
Xlabel 设置x轴标签
Xlim 获取或者设置x轴区间大小
Xscale 设置x轴缩放比例
Xticks 获取或设置x轴刻标和相应标签
Ylabel 设置y轴的标签
Ylim 获取或设置y轴的区间大小
Yscale 设置y轴的缩放比例
Yticks 获取或设置y轴的刻标和相应标签

Figure函数

函数名称 描述
Figtext 在画布上添加文本
Figure 创建一个新画布
Show 显示数字
Savefig 保存当前画布
Close 关闭画布窗口

第一个绘图程序

首先导入 Matplotlib 包中的 Pyplot 模块,并以 as 别名的形式简化引入包的名称。

1
import matplotlib.pyplot as plt

接下来,使用 NumPy 提供的函数 arange() 创建一组数据来绘制图像。

如果您对numpy库并不了解,可以理解为这就是在生成列表数据即可。

1
2
3
4
#引入numpy包
import numpy as np
#获得0到2π之间的数据,每个数据间隔0.05
x = np.arange(0, math.pi*2, 0.05)

我们这里来绘制sin函数的值。使用numpy库内置函数计算出值(实际上是矩阵),放入y中,作为函数值。

1
y = np.sin(x)

此时,使用plot函数进行绘制即可。绘制完后,需要使用show函数展示出来才行。

1
2
plt.plot(x,y)
plt.show()

image-20230318120404283

这个图像实在是光秃秃。我们在show之前添加一些属性设置。设置上图像的标题、标签。

1
2
3
plt.xlabel("angle")
plt.ylabel("sine")
plt.title('sine wave')

image-20230318120557553

这样,图像勉强能看了。

您也可以在 Jupyter 笔记本中运行 Matplotlib 的绘图程序。通过命令行或者开始菜单的方式启动 Jupyter 笔记本。启动成功后,将上述代码拷贝到输入行内,如下所示:

jupyter使用

%matplotlib inline 是 Jupyter 提供的魔法命令,它可以把输出图显示在笔记本内部,否则会以查看器的形式单独显示。

title、label、坐标轴设置

1
2
3
4
5
6
plt.title("title")#括号当中输入标题的名称
plt.xlim(0,6) #x轴坐标轴
plt.ylim((0, 3))#y轴坐标轴
plt.xlabel('X')#x轴标签
plt.ylabel('Y')#y轴标签
plt.show()

可以对相应属性进行设置。

其中,x、y坐标轴的设置,又一般使用plot函数进行设置。

Figure画布对象与Axes坐标轴对象

在matplotlib中,整个图像为一个Figure对象。在Figure对象中可以包含一个或者多个Axes对象。每个Axes(ax)对象都是一个拥有自己坐标系统的绘图区域

1
2
3
4
plt.figure(figsize=(6, 3))
plt.plot(6, 3)
plt.plot(3, 3 * 2)
plt.show()

image-20230318121336375

如果我们要在一个代码中生成多张图,就需要多个画布,也就是多个figure对象。那么此时,我们就转变为对各个画布对象进行操作,而非plt库的默认画布。

1
2
3
from matplotlib import pyplot as plt
#创建图形对象
fig = plt.figure()
参数 说明
figsize 指定画布的大小,(宽度,高度),单位为英寸。
dpi 指定绘图对象的分辨率,即每英寸多少个像素,默认值为80。
facecolor 背景颜色。
dgecolor 边框颜色。
frameon 是否显示边框。

有了画布,我们还要添加坐标轴对象。

1
ax = fig.add_axes([0.1,0.1,0.8,0.8])

add_axes() 的参数值是一个序列,序列中的 4 个数字分别对应图形的左侧,底部,宽度,和高度,且每个数字必须介于 0 到 1 之间。

即将画布的宽、高作为 1 个单位。比如,[ 0.1, 0.1, 0.8, 0.8],它代表着从画布 10% 的位置开始绘制, 宽高是画布的 80%。

坐标轴对象可以设置标题,设置标签,进行绘图。与原本的库一样的调用方式。

1
2
3
4
5
6
7
8
9
x = np.arange(0, math.pi*2, 0.05)
y = np.sin(x)
fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.plot(x,y)
ax.set_title("sine wave")
ax.set_xlabel('angle')
ax.set_ylabel('sine')
plt.show()

image-20230318123811971

label、legend图例设置

在画图时,可以添加label属性,传入图例。并通过legend启动,添加loc属性选择图例位置。

1
2
3
4
5
x = np.arange(0, math.pi*2, 0.05)
y = np.sin(x)
plt.plot(x,y,label="sin")
plt.legend(loc="best")#图例位置,可选best,center等
plt.show()

一图多线

在同一个figure下,直接使用plot进行画图即可。同一张图上可以全部显示出来。注意添加label参数以作区别。

如果要画多张图,可以在两个plot方法之间使用figure方法创造一个新的窗口,进行分别展示。

注释

有时候我们需要对特定的点进行标注,我们可以使用 plt.annotate 函数来实现:

s: 注释信息内容

xy:箭头点所在的坐标位置

xytext:注释内容的坐标位置

arrowprops:设置指向箭头的参数

1
2
3
4
5
6
x=np.linspace(0,10,200)#从0到10之间等距产生200个值
y=np.sin(x)

plt.plot(x,y,linestyle=':',color='b')
plt.annotate(text='here',xy=(3,np.sin(3)),xytext=(4,-0.5),weight='bold',color='b',arrowprops=dict(arrowstyle='-|>',color='k'))
plt.show()

image-20230318121953844

子图

如果需要将多张子图展示在一起,可以使用 subplot() 实现。即在调用 plot()函数之前需要先调用 subplot() 函数。

该函数的第一个参数代表子图的总行数,

第二个参数代表子图的总列数,

第三个参数代表活跃区域。

1
2
3
4
5
6
7
8
9
10
11
ax1 = plt.subplot(2, 2, 1)
plt.plot(x,np.sin(x), 'k')

ax2 = plt.subplot(2, 2, 2, sharey=ax1) # 与 ax1 共享y轴
plt.plot(x, np.cos(x), 'g')

ax3 = plt.subplot(2, 2, 3)
plt.plot(x,x, 'r')

ax4 = plt.subplot(2, 2, 4, sharey=ax3) # 与 ax3 共享y轴
plt.plot(x, 2*x, 'y')

image-20230318122150290

同样的,这些图像支持各自传入各种各样的参数。

plot的参数

plot函数支持传入各种参数,不需要在外部再手动设置。

1
2
3
4
#单条线:
plot([x], y, [fmt], data=None, **kwargs)
#多条线一起画
plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)

可选参数[fmt] 是一个字符串来定义图的基本属性如:颜色(color),点型(marker),线型(linestyle),

具体形式 fmt = ‘[color] [ marker ] [ line ]’

fmt接收的是每个属性的单个字母缩写。

=============    ===============================
character        color
=============    ===============================
``'b'``          blue 蓝
``'g'``          green 绿
``'r'``          red 红
``'c'``          cyan 蓝绿
``'m'``          magenta 洋红
``'y'``          yellow 黄
``'k'``          black 黑
``'w'``          white 白
=============    ===============================
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
=============    ===============================
character description
============= ===============================
``'.'`` point marker
``','`` pixel marker
``'o'`` circle marker
``'v'`` triangle_down marker
``'^'`` triangle_up marker
``'<'`` triangle_left marker
``'>'`` triangle_right marker
``'1'`` tri_down marker
``'2'`` tri_up marker
``'3'`` tri_left marker
``'4'`` tri_right marker
``'s'`` square marker
``'p'`` pentagon marker
``'*'`` star marker
``'h'`` hexagon1 marker
``'H'`` hexagon2 marker
``'+'`` plus marker
``'x'`` x marker
``'D'`` diamond marker
``'d'`` thin_diamond marker
``'|'`` vline marker
``'_'`` hline marker
============= ===============================
1
2
3
4
5
6
7
8
=============    ===============================
character description
============= ===============================
``'-'`` solid line style 实线
``'--'`` dashed line style 虚线
``'-.'`` dash-dot line style 点画线
``':'`` dotted line style 点线
============= ===============================

另外,支持color=,linestyle=,label=关键字传参,具体可参照官方文档,或参考上方plt.xxx设置。一般都有对应的参数。

各种其他图

参考绘图类型节即可。这里以柱状图为例。

1
2
3
4
x = np.arange(10)
y = np.random.randint(0,20,10)
plt.bar(x, y)
plt.show()