本文章记录Matplotlib绘图的初步介绍和基本逻辑,在了解其背后的逻辑之后,每次绘图的时候才能知道如何下手。顺着工具的理念去使用,才能得心应手地实现心中所想即所得。
Matplotlib绘图逻辑
作为Python的一个绘图包,Matplotlib继承了Python的一切接对象
的特点。绘图的过程,就可以看做是在绘图板上进行绘图的过程。当然,为了绘图的简单性和交互性,Matplotlib也提供了过程式或者命令式的函数编程。
Matplotlib绘图的逻辑基本上和自己绘画的流程是一样的。包括三个过程:
- 找到一张纸或者一块画布;
- 调色等一系列前戏;
- 作画。
按照上述过程的模拟,Matplotlib有三个基本模块:
- FigureCanvas
- Renderer
- Artist
三个模块分别实现上述的三个过程。其中,前两个模块主要涉及到和计算机底层的交互,暂时不用接触。我们绝大部分的工作,主要是在利用Artist接口。
Artist接口中包含两类对象:
- 一类是类似于曲线Line2D、文字text、图像image等等基本元素。
- 一类是容器对象,比如坐标系Axes、坐标轴Axis等等。
Matplotlib绘图方法
个人认为,Matplotlib主要有两种绘图逻辑:
- 对象式绘图
- 函数式绘图
其中,推荐使用对象式绘图方法,因为它可以更好地控制和自定义绘图。从Matplotlib官方文档中摘下来下图,显示了大部分的绘图元素:
绘图
本文章中主要使用Matplotlib的pyplot模块来实现绘图。
打开git bash
,进入ipython
界面,导入绘图模块:
1 | import matplotlib.pyplot as plt |
构建空白画布
按照对象式绘图的思想,首先需要使用plt.figure()
创建一个Figure
对象(个人理解相当于空白画布),通过plt.show()
显示出来:
1 | fig = plt.figure() |
这时,会显示出一个空的画布,如下图:
因为此时只是创建了一个画布,但是什么都没有画上去,所以肯定是一个空的。
另外,在创建Figure
对象的时候,可以使用figsize
和dpi
来控制图片的尺寸。比如:
1 | fig = plt.figure(figsize=(16, 8), dpi=100) |
figsize
表示画布的宽和高;dpi
表示每英寸的像素大小。因此,上面命令就会创建一个$1600\times{800}$的画布。
在空白画布上添加Axes对象
有了图像层,接下来就需要在图像层上来画画了,但是首先需要创建一个坐标轴,之后的绘图都以这个坐标轴为参考系来绘制。由此,我们调用Figure
对象的add_axes
方法:
1 | fig = plt.figure() |
其中,[0.1, 0.1, 0.8, 0.8]
表示在图像层中,坐标轴区域(坐标层)距离画布坐标0.1倍的位置,距离下边0.1倍位置,坐标轴区域的整体宽度和高度占整体图像层0.8倍的大小,也就是说,距离右边和上边分别也是1-0.8-0.1=0.1倍的大小。得到如下图:
可以看出,这里相当于在画布上加入了一个坐标系区域。
在Axes上绘制曲线
在画布上添加坐标系区域之后,现在就可以在该坐标系区域内进行绘制曲线了。比如,绘制sin
函数曲线:
1 | import numpy as np |
在这里,相当于在画布Figure
上创建了两个坐标系Axes
区域,然后分别在这两个坐标系区域中进行绘图。得到如下图:
保存图片
上面的示例中都是plt.show()
显示的是交互式的绘图界面,而不是输出的图片。如果要保存图片,还需要通过savefig()
保存。可以使用plt.savefig()
或者fig.savefig()
方法来保存。Matplotlib可以生成多种格式的图像,包括PNG
、JPG
、PDF
等等,只需要写好后缀名即可:
1 | 'result.png') fig.savefig( |
小结
总的来说,按照以上方法绘图的步骤是:
- 创建画布
Figure
- 在画布上添加坐标轴
Axes
- 在坐标轴上绘图
这种方法逻辑清晰,可以随心所欲地修改图片中的各种元素。
绘制子图AxesSubplot
在画布上还可以使用fig.add_subplot()
方法添加子图对象AxesSubplot
,这样,画布上能够绘制多个子图。 代码如下:
1 | import matplotlib.pyplot as plt |
得到如下图:
可以看出,
fig.add_subplot()
方法其实就是起到了添加坐标层Axes的作用,类似于之前的fig.add_axes()
。
过程式的绘图
以前在网上查找资料的时候,经常会看见这种写法,例如:
1 | x = np.linspace(0, 2, 100) |
官方说法是这个样子的:
Pyplot为底层面向对象的绘图库提供状态机接口。状态机隐式地自动创建图形和轴,以实现所需的图形。
也就是说,第一次调用plt.plot
的时候,会自动创建Figure
和Axes
对象以实现绘图。随后对plt.plot
的调用会重新使用当前的Axes
,设置标题、图例和轴标签同样还会自动使用当前Axes
。
总的来说,这种方式中,对象已经被隐式地掩盖了,但实质上,还是相当于在Axes
上进行绘图。
参考
PermaLink:
https://lyuhang.github.io/2020/06/23/Matplotlib%E7%BB%98%E5%9B%BE/