【matplotlib】可视化解决方案——如何正确理解pyplot和OO-API

概述

matplotlib 是一个 Python 绘图库,能够以多种硬拷贝格式和跨平台的交互式环境生成出版物质量的图形,可以用来绘制各种静态、动态、交互式的图表。matplotlib 提供了两种绘图接口:

  • 隐式 API:使用 pyplot 的 MATLAB 风格绘图接口;
  • 显式 API:使用面向对象的接口;

接下来我将会一一说明两种 API。

隐式 API

首先说一下 pyplot 模块,很多人对此有很大的误解,认为 pyplot 才是 matplotlib 库的核心,但实则不然,我们稍微深入研究一下 pyplot 库的源码,以绘制折线图为例,我们一般调用 plt.plot(),该方法的源码如下:

def plot(*args, scalex=True, scaley=True, data=None, **kwargs):  
    return gca().plot(  
        *args, scalex=scalex, scaley=scaley,  
        **({"data": data} if data is not None else {}), **kwargs)

def gca(**kwargs):  
    return gcf().gca(**kwargs)

可以看到真正执行折线图绘图指令的对象是 gcf().gca()gcf() 方法用来返回当前的 Figure 对象;而 gca() 方法返回当前的 Axes 对象。本质上还是在使用面向对象的方法。那为什么还需要 pyploy 这样的隐式 API 呢?

因为 matplotlib.pyplot 简单、直接,能够胜任我们想要解决的大多数任务。matplotlib 就是在这种类 MATLAB 的哲学思想下被设计出来的。帮助我们在绘图时减少指令的使用。甚至只需要一个指令就能完成任务(例如 plt.plot(x, y))。这样我们就不需要去思考对象、方法、属性、渲染后端、图表、画布和其他图形元素。

这样的机制能够让使用者快速地绘制数据,而不用换担心后台细节,比如 matplotlib 运行在什么样的平台,底层使用的渲染库是哪一个(GTK、QT、Tk)。所有的细节都隐藏在 matplotlib 内部。pyplot 这个有状态的接口处理创建图表和坐标轴的逻辑,并把它们与配置的后端联系在一起。同时它也为当前图表和坐标轴保存了数据,可以通过该模块的各种指令进行调用。

显式 API

显式 API 实现了所有被隐藏起来的棘手工作,如渲染图形元素、把图像渲染到平台的图形工具上、处理用户输入等。显式 API 使用面更广,也只有通过它才能进一步挖掘 matplotlib 库的潜力,这也是 matplotlib 官方推荐的使用方式。

使用显式 API 能帮助我们进一步了解 matplotlib 的构建。不论是什么形式的绘图,我们程序的输出结果就是一个 Figure 对象。Figure 对象是构成图像的所有其他元素的顶级容器,其他的元素都是它的子元素,统一叫做 Artist 对象。也可以把 Figure 对象当做一块画布,不同的 Artist 对象在其上进行绘制。

Figure对象全解

以上图为例,所有蓝色的元素都是 Artist 对象。这几乎包含了一个绘图的所有要素。从层级上来看,Figure 对象的下一级是 Axes 对象,也就是我们看到的一幅幅子图,一个 Figure 对象可以包含一个或者多个 Axes 对象;一个 Axes 对象除了包含数据形成的 Artist 对象,还包含一个或多个坐标轴,在 matplotlib 中坐标轴本身也是一个对象,称之为 Axis 对象,X 轴是 XAxis 对象,Y 轴是 YAxis 对象,他俩本质上都是 Axis 的子类实例。综上所述 Artist 对象包含 matplotlib 绘图的一切(文本、坐标轴、图形等等)。

小结

现在我们总结一下,如果将 matplotlib 看做一个软件,它由以下三个部分组成:

  1. matplotlib.pylab:这是用户用来创建类似 matplotlib 中图形的一组函数,这就是隐式 API;
  2. matplotlib API:用于创建和管理图形、文本、线条、图表等一组类,可以理解为显式 API(推荐使用);
  3. 后端:后端是绘图的驱动程序,用于将前端的抽象表示转换为一个个文件或者显式设备。

示例

接下来,举一个例子说明一下二者的区别,第一段代码使用 pyplot 的方式进行绘图;第二段使用面向对象这种显式 API 的方式绘制相同的图像。

# 使用pyplot的形式进行绘图  
x = np.linspace(0, 2 * np.pi, 1000)  
y = np.cos(x)  
plt.title("使用pyplot的方式进行绘图", fontsize=15)  
plt.plot(x, y, lw=3, color='orange')

plt.show()

画图结果如下:

pyplot的方式绘图
# 使用面向对象的方法进行绘图  
# 定义Figure对象  
fig = plt.figure()  
# 定义Axes对象  
ax = fig.add_subplot(111)  
# 定义Artist对象  
line_obj = Line2D(x, y, color='paleturquoise', lw=3, ls='--')  
# 添加Artist对象  
ax.add_artist(line_obj)  
ax.set_title("使用面向对象的方法绘图", fontsize=15)  
ax.set_xlim([0, 2 * np.pi])  
ax.set_ylim([-1, 1])  
  
plt.show()

画图结果如下:

面向对象绘图

补充说明

如果你想进行互动和探索编程,最好通过 Python 交互式 shell 使用 matplotib。为此,最有名的很可能就是 IPython pylab 模式了。它在一个强大并且自省的 shell 里提供 matplotlib 的所有特性。shell 具有一些丰富的特性如历史、内联绘图,如果你使用 IPython Notebook 的话还可以分享你的工作。

IPython Notebook 是一个基于 Web 的 IPython shell 界面, 我们可以把上面面的工作分享出去,或转换成 HTML 或 PDF。Matplotlib 图形已经被嵌入并内联在里面,因此它们也可以被保存下来或者分享出去。

往期回顾

  1. 【matplotlib】可视化解决方案——如何正确展示和保存图像
  2. 【matplotlib】可视化解决方案——如何设置字符串的输出字体效果
  3. 【matplotlib】可视化解决方案——如何正确使用颜色映射表
  4. 【matplotlib】可视化解决方案——如何调整轴脊位置
  5. 【matplotlib】可视化解决方案——如何设置坐标系计量方法
  6. 【matplotlib】可视化解决方案——如何正确使用文本注释
  7. 【matplotlib】可视化解决方案——如何调整计量单位和计量方法
  8. 【matplotlib】可视化解决方案——如何实现图形的动画效果
  9. 【matplotlib】可视化解决方案——如何正确使用plot方法
  10. 【matplotlib】可视化解决方案——如何向画布中添加坐标轴

文中难免会出现一些描述不当之处(尽管我已反复检查多次),欢迎在留言区指正,相关的知识点也可进行分享,希望大家都能有所收获!!如果觉得我的文章写得还行,不妨支持一下。你的每一个转发、关注、点赞、评论都是对我最大的支持!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容