一、实验介绍
1.1 实验内容
Matplotlib 是支持 Python 语言的开源绘图库,因为其支持丰富的绘图类型、简单的绘图方式以及完善的接口文档,深受 Python 工程师、科研学者、数据工程师等各类人士的喜欢。这是 Matplotlib 绘图课程的第一章节,将带你了解如何使用 Matplotlib 绘制 2D 图像。
1.2 实验知识点
- Matplotlib 绘制 2D 图像
1.3 实验环境
- python2.7
- Xfce 终端
- ipython 终端
1.4 适合人群
本课程难度为一般,属于初级级别课程,适合具有 Python 基础,并对使用 Matplotlib 绘图感兴趣的用户。
1.5 官方文档
学习本课程之前,你需要先下载官方文档,推荐保存到你的本地电脑上。Matplotlib 的内容量非常大(官方文档都有 3000 多页),课程侧重进行介绍并演示。部分补充内容,文中会给出官方文档的页码,方便课后自行查阅。
https://matplotlib.org/2.0.2/Matplotlib.pdf
二、Matplotlib 初探
在日常的工作和学习过程中,我们都会遇到需要针对数据进行绘图的时候。谈起数据绘图,你应该最先想到的是 Excel。Excel 操作起来相对简单,提供的图形样式也可以满足大部分人日常绘图的需要。但是,如果你处于工程、数据科学相关专业领域,使用 Excel 绘图就显得捉襟见肘了。首先,Excel 默认 提供的图形样式有限,其次是自定义程度不高。
很多时候,我们会使用到 Matlab 提供的绘图模块,又或者使用 Origin 进行绘图。这些软件固然都很不错,但均为商业软件,使用时需要获得授权。
今天介绍的 Matplotlib 就是一个可以媲美商业软件效果的开源绘图工具,你只需要掌握一点 Python 语言,就可以绘制出任何需要的图形。Matplotlib 拥有着十分活跃的社区以及稳定的版本迭代。选择 Matplotlib 无疑是和数据打交道时最明智的选择之一。
2.1 Matplotlib 安装
实验楼的在线环境,默认已经安装了 Matplotlib 1.3.1 版本。目前,Matplotlib 的最新稳定版本为 2.0.2。本课程内容基于实验楼在线环境版本,在本地测试时,某一些模块可能会有一些变化。
如果你想在本地安装 Matplotlib,可以这样做:
Linux:
Debian / Ubuntu : sudo apt-get install python-matplotlib
Fedora / Redhat : sudo yum install python-matplotlib
Windows & macOS:
python -m pip install -U pip setuptools
python -m pip install matplotlib
2.2 绘制简单的折线图需要几步?
我们都说了,Matplotlib 是一个非常简单而又完善的开源绘图库。那么它到底有多简单呢?
下面,我们通过 3 行代码绘制一张简单的折线图。你可以通过在线环境左下角的应用程序菜单 > 附件,打开 ipython 交互式终端
(本课程默认),并键入下面的代码。
from matplotlib import pyplot as plt
plt.plot([1,2,3,2,1,2,3,4,5,6,5,4,3,2,1])
plt.show()
我们可以看到,一张和山峰样式相似的折线图就绘制出来了。接下来,我们来解析一下这三行代码的含义。
from matplotlib import pyplot as plt
第一行代码是从 Matplotlib 中导入了 pyplot
绘图模块,并将其简称为 plt
。pyplot 模块是 Matplotlib 最核心的模块,几乎所有样式的 2D 图形都是经过该模块绘制出来的。这里简称其为 plt
是约定俗成的,希望你也这样书写代码,以便拥有更好的可读性。
plt.plot([1,2,3,2,1,2,3,4,5,6,5,4,3,2,1])
plt.plot()
是 pyplot
模块下面的直线绘制(折线图)方法类。示例中包含了一个[1,2,3,2,1,2,3,4,5,6,5,4,3,2,1]
列表,这里默认代表将该列表作为 y
值,而 x
值会从 0
到 n-1
。
plt.show()
最后一行代码表示将图显示出来。
2.3 除了折线图,怎样绘制其他图?
上面演示了如何通过 3 行代码绘制一张折线图。那么,除了折线图,我们平常还要绘制柱状图、散点图、饼状图等等。这些图应该怎样绘制呢?
上文中,我们提到了 pyplot
模块,其中 pyplot.plot
方法是用来绘制折线图的。你应该会很容易联想到,更改后面的方法类名就可以更改图形的样式,会是这样的吗?
的确,在 Matplotlib 中,大部分图形样式的绘制方法都存在于 pyplot
模块中。例如:
方法 | 含义 |
---|---|
matplotlib.pyplot.angle_spectrum | 绘制电子波谱图 |
matplotlib.pyplot.bar | 绘制柱状图 |
matplotlib.pyplot.barh | 绘制直方图 |
matplotlib.pyplot.broken_barh | 绘制水平直方图 |
matplotlib.pyplot.contour | 绘制等高线图 |
matplotlib.pyplot.errorbar | 绘制误差线 |
matplotlib.pyplot.hexbin | 绘制六边形图案 |
matplotlib.pyplot.hist | 绘制柱形图 |
matplotlib.pyplot.hist2d | 绘制水平柱状图 |
matplotlib.pyplot.imshow | 以图像显示 |
matplotlib.pyplot.pie | 绘制饼状图 |
matplotlib.pyplot.quiver | 绘制量场图 |
matplotlib.pyplot.scatter | 散点图 |
matplotlib.pyplot.specgram | 绘制光谱图 |
matplotlib.pyplot.subplot | 绘制子图 |
除此之外,对图像样式的微调,包括标注、填充、自定义坐标轴等也同样包含在 pyplot
模块中。例如:
方法 | 含义 |
---|---|
matplotlib.pyplot.annotate | 绘制图形标注 |
matplotlib.pyplot.axhspan | 绘制垂直或水平色块 |
matplotlib.pyplot.clabel | 标注轮廓线 |
matplotlib.pyplot.fill | 填充区域 |
matplotlib.pyplot
模块下一共包含了 160
余个不同的方法(官方文档 p1387),这些方法涉及到图像绘制的方方面面,这里就不再一一罗列。在后面的实验中,我们会慢慢接触到其中最常用的方法,这些方法足以满足大部分绘图需求。
三、2D 图像绘制
下面,我们就来一些常见类型的图像绘制及参数使用。
3.1 线型图
方法:matplotlib.pyplot.plot(*args, **kwargs)
上面我们见到使用该方法来绘制折线图。其实,matplotlib.pyplot.plot(*args, **kwargs)
方法严格来讲可以绘制线型图或者样本标记。其中,*args
允许输入单个 y
值或 x,y
值。
例如,我们这里绘制一张自定义 x,y 的曲线图。绘制点什么好呢?那就正弦曲线吧。
from matplotlib import pyplot as plt #载入 pyplot 绘图模块
import numpy as np # 载入数值计算模块
# 在 -2PI 和 2PI 之间等间距生成 1000 个值,也就是 X 坐标
X = np.linspace(-2*np.pi, 2*np.pi, 1000)
# 计算 y 坐标
y = np.sin(X)
# 向方法中 `*args` 输入 X,y 坐标
plt.plot(X, y)
plt.show()
这样,1 条正弦曲线就绘制出来了。但值得注意的是,pyplot.plot 在这里绘制的正弦曲线,实际上不是严格意义上的曲线图,而在两点之间依旧是直线。这里看起来像曲线是因为样本点相互挨得很近。
3.2 柱形图
方法:matplotlib.pyplot.bar(*args, **kwargs)
柱形图大家应该都非常了解了。这里,我们直接用上面的线性图的代码,仅把 plt.plot(X, y)
改成 plt.bar(X, y)
试一下。
效果好像不太好,问题当然是出在这里:X = np.linspace(-2*np.pi, 2*np.pi, 1000)
。横坐标是等间距生成的 1000
个值,效果当然会堆积在一起了。尝试把 1000
改成 10
再试一次。
from matplotlib import pyplot as plt #载入 pyplot 绘图模块
import numpy as np # 载入数值计算模块
# 在 -2PI 和 2PI 之间等间距生成 10 个值,也就是 X 坐标
X = np.linspace(-2*np.pi, 2*np.pi, 10)
# 计算 y 坐标
y = np.sin(X)
# 向方法中 `*args` 输入 X,y 坐标
plt.bar(X, abs(y)) # y 值取绝对值
plt.show()
柱形图的样式终于出来了。
3.3 散点图
方法:matplotlib.pyplot.scatter(*args, **kwargs)
散点图就是呈现在二维平面的一些点,这种图像的需求也是非常常见的。比如,我们通过 GPS 采集的数据点,它会包含经度以及纬度两个值,这样的情况就可以绘制成散点图。下面,我们画一个试试。
from matplotlib import pyplot as plt #载入 pyplot 绘图模块
import numpy as np # 载入数值计算模块
# X,y 的坐标均有 numpy 在 0 到 1 中随机生成 1000 个值
X = np.random.normal(0,1,1000)
y = np.random.normal(0,1,1000)
# 向方法中 `*args` 输入 X,y 坐标
plt.scatter(X, y)
plt.show()
3.4 饼状图
方法:matplotlib.pyplot.pie(*args, **kwargs)
饼状图在有限列表以百分比呈现时特别有用,你可以很清晰地看出来各类别之间的大小关系,以及各类别占总体的比例。
from matplotlib import pyplot as plt #载入 pyplot 绘图模块
Z = [1, 2, 3, 4, 5]
# 绘图
plt.pie(Z)
plt.show()
这里的 Z 值反映了互相之间的大小关系,而无论输入多少个值,最终都是在一张饼(100%)里瓜分。
3.5 量场图
方法:matplotlib.pyplot.quiver(*args, **kwargs)
量场图就是由向量组成的图像,在气象学等方面被广泛应用。从图像的角度来看,量场图就是带方向的箭头符号。
from matplotlib import pyplot as plt #载入 pyplot 绘图模块
import numpy as np # 载入数值计算模块
# 生成数据矩阵
X, y = np.mgrid[0:10, 0:10]
# 绘图
plt.quiver(X, y)
plt.show()
3.6 等高线图
方法:matplotlib.pyplot.contourf(*args, **kwargs)
中学学习地理的时候,我们就知道等高线了。等高线图是工程领域经常接触的一类图,那么如何用 Matplotlib 画出来呢?
from matplotlib import pyplot as plt #载入 pyplot 绘图模块
import numpy as np # 载入数值计算模块
# 生成数据
x = np.linspace(-5, 5, 500)
y = np.linspace(-5, 5, 500)
X, Y = np.meshgrid(x, y)
Z = (1 - X / 2 + X ** 3 + Y ** 4) * np.exp(-X ** 2 - Y ** 2)
# 绘图
plt.contourf(X, Y, Z)
plt.show()
值得注意的是,当我们向 contourf(X,Y,Z)
传入数据时,一定要注意相互之间的维度关系,不然很容易报错。其中,当 X,Y,Z 都是 2 维数组时,它们的形状必须相同。如果都是 1 维数组时,len(X)
是 Z 的列数,而 len(Y)
是 Z 中的行数。
2 维数组示例:
X = [[1, 2], [3, 4]]
Y = [[1, 2], [3, 4]]
Z = [[1, 2], [3, 4]]
1 维数组示例:
X = [1, 2]
Y = [-1, -2, -3]
Z = [[1, 2], [3, 4], [5, 6]]
四、实验总结
本次实验对 pyplot 里包含的绘图方法进行了初步熟悉,并学会使用这些方法的默认参数绘制简单的图形样式。接下来的进阶实验将学习方法中提供的参数,绘制更为复杂漂亮的 2D 图像。
五、课后习题
1.自行阅读官方文档从 1387 页开始对 [matplotlib.pyplot
] 模块的介绍内容。对本章节介绍过的方法加深印象。若有余力,学习并掌握剩余没有介绍的方法。