Python 中的科学绘图
在之前的几篇文章中,我介绍了几个不同的 Python 模块,它们对于进行计算非常有用。但是,有哪些工具可以帮助您分析这些计算的结果呢?虽然您可以进行一些统计分析,但有时最好的工具是以图形方式表示结果。人类的大脑非常擅长发现模式和查看视觉信息中的趋势。为此,用于此类工作的标准 Python 模块是 matplotlib。借助 matplotlib,您可以创建复杂的数据图形,以帮助您发现关系。
您始终可以从源代码安装 matplotlib;但是,从您的发行版的软件包管理器安装它更容易。例如,在基于 Debian 的发行版中,您可以使用以下命令安装它
sudo apt-get install python-matplotlib
python-matplotlib-doc 软件包还包括 matplotlib 的额外文档。
与其他大型 Python 模块一样,matplotlib 也被分解为几个子模块。让我们从 pyplot 开始。这个子模块包含您想要用来绘制数据图形的大多数函数。由于涉及的名称很长,您可能希望将其导入为更短的名称。在以下示例中,我使用
import matplotlib.pyplot as plt
matplotlib 的底层设计模仿了 R 统计软件包的图形模块。图形函数分为两大类:高级函数和低级函数。这些函数不直接与您的屏幕交互。所有的图形生成和操作都通过抽象的图形显示设备进行。这意味着这些函数的行为方式相同,所有的显示细节都由图形设备处理。这些图形设备可以代表显示屏幕、打印机甚至文件存储格式。一般的工作流程是在抽象图形设备的内存中完成所有的绘图。然后,您将最终图像一次性推送到物理设备上。
最简单的例子是绘制存储为列表的一系列数字。代码如下所示
plt.plot([1,2,3,4,3,2,1]) plt.show()
第一个命令将给定列表中存储的数据绘制成常规散点图。如果您只有一个值列表,则假定它们是 y 值,列表索引给出 x 值。由于您没有设置特定的图形设备,matplotlib 假定默认设备映射到您正在使用的任何物理显示器。执行第一行后,您不会在显示器上看到任何内容。要看到一些东西,您需要执行第二个 show()
命令。这会将图形数据推送到物理显示器(图 1)。您应该注意到窗口底部有几个控制按钮,允许您执行诸如将图像保存到文件之类的操作。您还会注意到,您生成的图形相当简单。您可以使用以下命令添加标签
plt.xlabel('Index')
plt.ylabel('Power Level')

图 1. 基本散点图窗口包括窗格底部的控件。
然后,您将获得一个具有更多上下文的图形(图 2)。您可以使用 title()
命令为您的绘图添加标题,并且 plot
命令甚至比这更通用。您可以更改正在使用的绘图图形以及颜色。例如,您可以使用 g^
制作绿色三角形,或使用 bo
制作蓝色圆圈。如果您希望在单个窗口中绘制多个绘图,您只需将它们作为额外的选项添加到 plot()
中。因此,您可以使用类似这样的命令在同一绘图上绘制正方形和立方体
t = [1.0,2.0,3.0,4.0]
plt.plot(t,[1.0,4.0,9.0,16.0],'bo',t,[1.0,8.0,27.0,64.0],'sr')
plt.show()

图 2. 您可以使用 xlabel 和 ylabel 函数添加标签。
现在您应该在新绘图窗口中看到两组数据(图 3)。如果您导入 numpy 模块并使用数组,您可以将绘图命令简化为
plt.plot(t,t**2,'bo',t,t**3,'sr')

图 3. 您可以使用单个命令绘制多个绘图。
如果您想在绘图中添加更多信息,比如文本框怎么办?您可以使用 text()
命令来做到这一点,您可以设置文本框的位置及其内容。例如,您可以使用
plt.text(3,3,'This is my plot')
这将在 x=3, y=3 处放置一个文本区域。注释是文本框的一种特殊形式。这是一个链接到特定数据点的文本框。您可以使用 xytext
参数定义文本框的位置,并使用 xy
参数定义感兴趣的点的位置。您甚至可以使用 arrowprops
参数设置连接两者的箭头的详细信息。一个例子可能看起来像这样
plt.annotate('Max value', xy=(2, 1), xytext=(3, 1.5),
↪arrowprops=dict(facecolor='black', shrink=0.05),)
还有其他几个高级绘图命令可用。bar()
命令允许您绘制数据的条形图。您可以使用各种输入参数更改宽度、高度和颜色。您甚至可以使用 xerr
和 yerr
参数添加误差条。类似地,您可以使用 barh()
命令绘制水平条形图。或者,您可以使用 boxplot()
命令绘制箱线图。您可以使用 contour()
命令创建简单的等高线图。如果您想要填充的等高线图,请使用 contourf()
。hist()
命令将绘制直方图,并提供控制 bin 大小等项目的选项。甚至还有一个名为 xkcd()
的命令,它设置了许多参数,以便所有后续绘图都将采用与 xkcd 漫画相同的风格。
有时,您可能希望能够与图形进行交互。matplotlib 需要与几个不同的工具包(如 GTK 或 Qt)进行交互。但是,您不想为每个可能的工具包编写代码。pyplot 子模块包括以 GUI 不可知的方式添加事件处理程序的能力。FigureCanvasBase 类包含一个名为 mpl_connect()
的函数,您可以使用它将一些回调函数连接到事件。例如,假设您有一个名为 onClick()
的函数。您可以使用以下命令将其附加到按钮按下事件
fig = plt.figure()
...
cid = fig.canvas.mpl_connect('button_press_event', onClick)
现在,当您的绘图收到鼠标点击时,它将触发您的回调函数。它返回一个连接 ID,在本例中存储在变量 cid
中,您可以使用它来处理此回调函数。当您完成交互时,可以使用以下命令断开回调函数的连接
fig.canvas.mpl_disconnect(cid)
如果您只需要进行基本交互,您可以使用 ginput()
命令。它将监听一段时间,并返回绘图上发生的所有点击的列表。然后,您可以处理这些点击并进行某种交互式工作。
我在这里要介绍的最后一件事是动画。matplotlib 包括一个名为 animation 的子模块,它提供了生成数据 MPEG 视频所需的所有功能。这些电影可以由各种文件格式的帧组成,包括 PNG、JPEG 或 TIFF。有一个名为 Animation 的基类,您可以对其进行子类化并添加额外的功能。如果您对做太多的工作不感兴趣,那么已经包含了子类。其中一个子类 FuncAnimation 可以通过重复应用给定的函数并生成动画帧来生成动画。还有几个其他低级函数可用于控制电影文件的创建、编码和写入。您应该拥有生成您可能需要的任何电影文件所需的所有控制。
现在您已经掌握了 matplotlib,您可以为您的最新论文生成一些真正令人惊叹的视觉效果。此外,您还可以通过绘制图形来找到新的和有趣的关系。所以,去检查您的数据,看看那里可能隐藏着什么。