约定
我们导入matplotlib时,推荐使用:
import matplotlib as mpl
因此,简洁起见,在后面我们将经常使用 mpl 代表 matplotlib。
还将用:
有一部分初学者,因为对位图、矢量图、分辨率、DPI、PPI、图像尺寸、坐标等概念的不清晰,也造成了学习、使用mpl的一些困扰。
将会专门以一篇文章,用草根的语言讨论一下这些基本概念,理清这些概念对理解matplotlib框架非常有好处。
Matplotlib是基于Python语言,旨在为Python提供一个数据绘图包的开源项目,它以Python的一个库包的形式分发、安装、调用。
mpl是Python的一个包,记住:Python包就是一个定义了__init__.py文件的文件夹而已,包中的各个模块都会保存在这个文件夹中。
matplotlib 实际上就是提供了 3 种API,用于不同的绘图场景。
mpl需要其它包的支持,主要有:
matplotlib是受MATLAB的启发构建的,MATLAB语言是面向过程的,利用函数的调用,MATLAB中可以轻松的利用一行命令来绘制直线,然后再用一系列的函数调整结果。
matplotlib通过matplotlib.pyplot模块,完全仿照MATLAB的函数形式,提供了一套绘图接口。这套函数接口方便MATLAB用户过度到matplotlib包。
Python中的函数式编程是通过封装对象实现的。matplotlib中的函数式调用其实也是如此。matplotlib本质上还是构建对象来构建图像。只不过pyplot函数将构建对象的过程封装在函数中,从而让我们觉得很方便。
pyplot函数式绘图创造了一个仿真MATLAB的工作环境,并有许多成形的绘图函数,如果只是作为Matplotlib的一般用户,pyplot可以满足大部分的需求。
但利用函数式绘图会有以下缺点:
第4、5组成了一个陷阱,它就是困住很多初学者的那个最大的坑。
再看下面的函数绘图的示例:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.show()
对于初学者来说,它很简单,也很容易模仿,但很多人不知道,函数封装的一些东西在后台做了些什么,因此长时间只能照猫画虎。
我们改用**面向对象(OO, object-oriented)**绘图方式绘制上面的直线图。
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
line, = ax.plot([1, 2, 3, 4])
s, (width, height) = canvas.print_to_buffer()
from PIL import Image
im = Image.frombytes("RGBA", (width, height), s)
im.show()
大家先复制这些代码,运行看看就可以了,后面会详细解释它们。
因为,面向对象绘图需要我们一步一步地创建需要的对象,包括基础的Figure,FigureCanvasAgg(画布),这需要引入两个类: Figure和mpl.backends.backend_agg.FigureCanvasAgg。所以代码看其来要长得多、复杂得多。
但这时,我们反而非常清楚我们创建的每个对象,对象之间的关系,以及我们正在做什么。
函数式编程也调用了这些类,只是调用的过程被函数调用所遮掩,所以初学者对函数创建的对象常是模糊的,似懂非懂的。函数式绘图提供了状态机接口,会自动对当前对象进行绘图操作,所以对象的调用思路也是不清晰的。
而面向对象绘图不同,每个对象都是你明确创建的,要对哪个对象进行操作也是显式调用的,所以你就知其然且知其所以然。
以我个人的经验,认为:从面向对象绘图开始才是学习matplotlib的正确姿势!
跟着我前进,等你学习一段时间后,你就会有打通matplotlib修炼任督二脉的感觉。
matplotlib.pylab是一个模块,它在单个名称空间中批量导入matplotlib.pyplot、numpy以及一些附加函数用于绘图。 最初的目的是通过将所有函数导入全局命名空间来模仿类似MATLAB的工作方式。由于大量导入全局命名空间可能会导致意外行为,现在这被认为是糟糕的风格。因此强烈建议不要使用pylab。 事实上在matplotlib的最新版中已弃用它。
因此,后面,我们将认为mpl只有pyplot函数式绘图和面向对象绘图两套API。
关于mpl框架的更详细介绍请见后续更新。
(This end.)