Python数据可视化编程实战

978-7-115-38439-3
作者: 【爱尔兰】Igor Milovanović
译者: 颛青山
编辑: 陈冀康

图书目录:

详情

本书针对有一定基础的Python程序员,包含了一系列实用的秘笈,帮助读者掌握如何使用Python及其流行的可视化和数据管理库来进行数据可视化。全书包含了60多个实际的案例,涉及到使用地图可视化数据、创建3D动画数据可视化、从各种格式导入数据,将数据导出为各种格式等实用技巧。

图书摘要

Python数据可视化编程实战
[爱尔兰]lgor Miloveanović 著

颛清山 译

人民邮电出版社

北京

图书在版编目(CIP)数据

Python数据可视化编程实战/(爱尔兰)米洛万诺维奇(Milovanovic,I.)著;颛清山译.--北京:人民邮电出版社,2015.5

ISBN 978-7-115-38439-3

Ⅰ.①P… Ⅱ.①米…②颛… Ⅲ.①软件工具—程序设计 Ⅳ.①TP311.56

中国版本图书馆CIP数据核字(2015)第057566号

版权声明

Copyright ©2013 Packt Publishing. First published in the English language under the title Python Data Visualization Cookbook.

All rights reserved.

本书由英国Packt Publishing公司授权人民邮电出版社出版。未经出版者书面许可,对本书的任何部分不得以任何方式或任何手段复制和传播。

版权所有,侵权必究。

◆著 [爱尔兰]Igor Milovanović

译 颛清山

责任编辑 陈冀康

责任印制 张佳莹 焦志炜

◆人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

三河市海波印务有限公司印刷

◆开本:800×1000 1/16

印张:16.75

字数:318千字  2015年5月第1版

印数:1-3000册  2015年5月河北第1次印刷

著作权合同登记号 图字:01-2013-9037号

定价:49.00元

读者服务热线:(010)81055410 印装质量热线:(010)81055316

反盗版热线:(010)81055315

内容提要

本书是一本使用 Python 实现数据可视化编程的实战指南,介绍了如何使用 Python 最流行的库,通过60余种方法创建美观的数据可视化效果。

全书共8章,分别介绍了准备工作环境、了解数据、绘制并定制化图表、学习更多图表和定制化、创建 3D 可视化图表、用图像和地图绘制图表、使用正确的图表理解数据以及更多的matplotlib知识。

本书适合那些对Python编程有一定基础的开发人员阅读,可以帮助读者从头开始了解数据、数据格式、数据可视化,并学会使用Python可视化数据。

译者序

图形可视化是展示数据的一个非常好的手段,好的图表自己会说话。毋庸多言,在Python的世界里,matplotlib是最著名的绘图库,它支持几乎所有2D绘图和部分3D绘图,被广泛地应用在科学计算和数据可视化领域。但是介绍matplotlib的中文书籍很少,大部分书籍只是在部分章节中提到了matplotlib的基本用法,因此在内容和深度上都力有不逮。本书则是一本专门介绍matplotlib的译著。

matplotlib 是一个开源项目,由 John Hunter 发起。关于 matplotlib 的由来,有一个小故事。John Hunter 和他研究癫痫症的同事借助一个专有软件做脑皮层电图分析,但是他所在的实验室只有一份该电图分析软件的许可。他和许多一起工作的同事不得不轮流使用该软件的硬件加密狗。于是,John Hunter 便有了开发一个工具来替代当前所使用的软件的想法。当时MATLAB被广泛应用在生物医学界中,John Hunter等最初是想开发一个基于MATLAB的版本,但是由于MATLAB的一些限制和不足,加上他本身对Python非常熟悉,于是就有了matplotlib的诞生。

所以,无论从名字上,还是从matplotlib提供的函数名称、参数及使用方法都与MATLAB非常相似。对于一个MATLAB开发人员,使用起来会相当得心应手。即使对不熟悉MATLAB的开发人员(譬如我),对其函数的使用也能够一目了然,而且matplotlib有着非常丰富的文档和实例,加上本书的介绍,学习起来将会非常轻松。

matplotlib 命令提供了交互绘图的方式,在 Python 的交互 shell 中,我们可以执行matplotlib命令来实时地绘制图形并对其进行修改。生成的图像可以保存成许多格式,这取决于其所使用的后端,但绝大多数后端都支持如png、pdf、ps、eps和svg等格式。

在之前的项目中,我使用Python的Locust工具进行性能测试,该工具非常出色,然而在对获取到的性能数据的分析上,没有提供太多的功能。于是我决定使用 matplotlib 进行性能数据的分析和可视化。从绘制最简单的柱状图、线形图,到引入散点图、直方图,我渐渐对matplotlib有了进一步的了解,也对它提供了如此强大的功能却又不失易用性而着迷。

虽然本书是一本cookbook,然而它并不仅仅局限在讲解如何绘制各种图形上,更重要的是,本书让我们了解了如何用正确的图形把数据可视化出来,也就是“do the right thing in the right way”。在翻译本书的过程中,我意识到,如果我当时手头有这么一本书,将会少走不少弯路。本书包括了非常多的图形介绍以及丰富的示例,我相信,读完本书以后,读者将能应对各种常见的数据可视化问题。

在这里,我要特别感谢一下我的妻子董秋影,在精神和专业知识上她都给予了我莫大的帮助,没有她就没有这本译稿的完成。她从事医疗图像算法工作,对各种图形和算法以及MATLAB都有很深的了解,本书的每一章都经过了她认真的审阅校对。此外,感谢彭明伟先生完成了第1章的初稿翻译工作。最后,感谢人民邮电出版社陈冀康老师专业细心地审核,和陈老师合作很轻松、很开心。

由于译者水平有限,错误和失误在所难免,如有任何意见和建议,请不吝指正,我将感激不尽。我的邮箱:zhuanqingshan@163.com。

颛清山

2014年12月于北京

作者简介

Igor Milovanović是一个在Linux系统和软件工程领域有深厚背景的经验丰富的开发人员。具备创建可扩展数据驱动分布式富软件系统的技术。

他是一个高性能系统设计的布道者,对软件架构和开发方法论有着浓厚的兴趣。他一直坚持倡导促进高质量软件的方法论,如测试驱动开发、一键部署和持续集成。

他也拥有坚实的产品开发知识。拥有领域经验知识,并参加过官方培训,他能够在业务和开发人员之间很好地传递业务知识和业务流程。

非常感谢我的未婚妻,她允许我把大量的时间花费在工作上而没有陪伴她,并在我无休止地谈论本书时甘愿做一个热心的听众。我也想感谢我的哥哥,他一直是我坚强的后盾。感谢我的父母,给予我各种发展自己的空间,让我成为今天的自己。

如果没有开发Python、matplotlib和所有本书中使用的库的开源社区的巨大能量,我不可能写出这本书。我深深地感谢所有这些项目背后的人们。感谢你们!

评阅者简介

Tarek Amr 从东安格里亚大学获得了数据挖掘和信息检索专业的研究生学位。他在软件开发领域有近 10 年的经验。自从 2007 年开始,他一直在 Global Voices Online (GVO)义务工作,目前他是埃及 Open Knowledge Foundation (OKFN)的大使。他热衷于开放数据、Government 2.0、数据可视化、数据新闻、机器学习和自然语言处理。

Tarek的Twitter账号是@gr33ndata,主页是http://tarekamr.appspot.com/。

Jayesh K. Gupta是Matlab Toolbox for BiclusteringAnalysis (MTBA)的首席开发人员。他目前是一名IIT Kanpur的在读研究生和研究员。他的兴趣是模式识别。他对基础科学也有浓厚的兴趣,认为它们是自然界中的模式分析工具。来到IIT之后,他看到这种分析是如何借助机器学习算法广泛应用在各种不同的应用程序中的。他相信通过机器智能来强化人类的想法是增进人类知识的最好方式之一。他是一个长期的技术爱好者和自由软件的布道者。他的网名是rejuvyesh。他也是一名狂热的读者,从Goodreads可以获得他读过的书籍的信息。从Bitbucket和GitHub可以找到他的项目。所有的链接都在http://home.iitk.ac.in/~jayeshkg/上,也可以通过a2z.jayesh@gmail.com联系他。

Kostiantyn Kucher 出生在乌克兰敖德萨。2012 年他在敖德萨国立理工大学获得了计算机科学专业的硕士学位。他使用Python、Matplotlib和PIL从事机器学习和图像识别的工作。

目前,Kostiantyn是一名计算机科学专业信息可视化方向的博士研究生。他在Andreas Kerren博导的指导下,在瑞典林奈大学计算机科学系的ISOVIS小组进行研究。

Kenneth Emeka Odoh从事高级的数据可视化技术研究工作。他的研究兴趣是通过可视的线索指导用户得出研究结果的探索性研究。

Kenneth 精通 Python 编程。2012 年他曾在芬兰的 Pycon 大会做演讲,主题是 Django中的数据可视化。

他目前是加拿大里贾纳大学的一名研究员,通晓多种编程语言,有 C、C++、Python和Java的应用开发经验。

编写代码之余,Kenneth还参加了坎皮恩学院圣歌合唱团。

前言

最好的数据是我们能看到并理解的数据。作为一个开发人员,我们想创造并构建出最全面且容易理解的可视化图形。然而这并非总是很简单,我们需要找出数据,读取它、清理它、揣摩它,然后使用恰当的工具将其可视化。本书通过简单(和不那么简单)直接的方法解释了如何读取、清理和可视化数据的流程。

本书对怎样读取本地数据、远程数据、CSV、JSON以及关系型数据库中的数据,都进行了讲解。

通过matplotlib,我们能用一行简单的Python代码绘制出一些简单的图表,但是进行更高级的绘图还需要除 Python 之外的其他知识。我们需要理解信息理论和人类的审美学来生成最吸引人的可视化效果。

本书讲解在Python中使用matplotlib绘图的一些练习、使用情况,以及对于不同图表特性应该使用的方法的一些最佳实践。

本书的写作及代码开发均基于 Ubuntu 12.03,使用了 Python 2.7、IPython 0.13.2、virtualenv 1.9.1、matplotlib 1.2.1、NumPy 1.7.1 和 SciPy 0.11.0。

本书涵盖内容

第1章,准备工作环境,包括一些安装方法,以及如何在你的平台上安装所需的Python包和库的一些建议。

第2章,了解数据,介绍通用的数据格式,以及如何读写,如CSV、JSON、XSL或者关系型数据库。

第3章,绘制图表及定制化,着手绘制简单的图表并介绍图表的定制化。

第4章,学习更多图表和定制化,继续上一章内容,介绍更多的高级表格和网格定制化。

第5章,3D可视化,介绍三维数据的可视化,如3D柱状图、3D直方图,以及matplotlib动画。

第6章,用图像和地图绘制图表,涵盖图像处理、在地图上投射数据,以及创建CAPTCHA测试图像。

第7章,使用正确的图表理解数据,涵盖一些更高级绘图技术的讲解和方法,如频谱图和相关性。

第8章,更多的matplotlib知识,介绍一些图表如甘特图、箱线图,并且介绍如何在matplotlib中使用LaTeX渲染文本。

准备工作

学习本书时,需要你在自己的操作系统上安装 Python2.7.3 或最新版本。本书使用Ubuntu12.03系统上的默认Python版本(2.7.3)。

本书中用到的另一个软件包是 IPython,它是一个交互式的 Python 环境,功能非常强大、灵活。可以通过基于 Linux 平台的包管理工具或者用于 Windows 和 Mac OS 系统的预安装文件安装。

一般来说,如果你对于Python安装和相关软件安装不熟悉,强烈推荐你使用预打包的Python 科学发行包如 Anaconda、Enthought Python 发行包或者 Python(X,Y)进行安装。

其他所需的软件主要包括Python包,可全部通过Python安装管理器pip进行安装。pip本身通过Python的easy_install安装工具安装。

谁适合阅读本书

本书是为那些通常已经了解Python编程的开发人员编写的。如果你听说过数据可视化但又不知道从何入手,本书会从头开始指导你了解数据、数据格式、数据可视化,以及如何使用Python可视化数据。

你需要知道一些一般的编程概念,如果你有编程经验,会非常有用。然而,本书中的代码几乎是逐行讲解的。阅读本书不需要任何数学知识,书中介绍的每一个概念都有详细的讲解,并且提供了一些参考资料以供进一步的兴趣阅读。

约定

在本书中,不同的信息由一些不同风格的文字来区分。这里有一些文字风格的例子,以及它们的含义解释。

书中的代码文字显示如下:“我们把小演示程序封装在DemoPIL类中,这样可以共享示例函数run_fixed_filters_demo的代码,并能很容易地对其进行扩展。”

代码块设置如下:

def _load_image(self, imfile):

self.im = mplimage.imread(imfile)

当我们想要让你关注代码块中的某一特定部分时,相关的行或元素将设置为粗体:

# tidy up tick labels size

all_axes = plt.gcf().axes

for ax in all_axes:

for ticklabel in ax.get_xticklabels() + ax.get_yticklabels():

ticklabel.set_fontsize(10)

所有的命令行输入或者输出的写法如下。

$ sudo python setup.py install

新术语关键词将显示为粗体。例如,在屏幕上、菜单或对话框中的文字将会显示为:“然后我们为火柴杆图设置一个标签和基线位置,默认值为0。”

警告或者重要的说明出现在这样的一个文本框中。

提示和技巧像这样显示。

读者反馈

欢迎读者向我们反馈意见。请让我们知道你对本书的看法——哪些是你喜欢或者不喜欢的。读者反馈对我们非常重要,可以帮我们完善一些你非常关心的内容。

如果给我们发送一般的反馈,可以简单地发电子邮件到feedback@packtpub.com,并请在消息标题中提及书名。

如果你对某个话题有经验,并且有兴趣写作或者想为一本书做贡献,请参考我们的作者指南www.packtpub.com/authors。

支持

既然你已经是Packt书籍的读者,我们有许多辅助材料可以帮助你从本书中得到最大的收获。

下载示例代码

可以在 http://www.packtpub.com 网站上你的账户中下载你所购买的所有图书的示例代码文件。如果你在其他地方购买本书,可以访问http://www.packtpub.com/support页面进行登记,文件会通过邮件直接发送给你。

勘误

尽管我们已经竭尽全力确保本书内容的准确,但是错误在所难免。如果你在书中发现了错误——可能是文本或者代码中的错误——如果你能把它报告给我们,我们将万分感谢。如此,这样可以减轻其他读者的痛苦,并且可以帮我们改进该书的后续版本。如果你找到任何错误,请访问http://www.packtpub.com/submit-errata并报告给我们,选择你的图书,点击 errata submission form 链接,并加入你勘误的详细内容。一旦你的勘误通过验证,你的提交将被接受,勘误将会上传到我们的网站,或者添加到位于该标题的勘误部分的已有勘误列表中。可以在http://www.packtpub.com/support上选择你的标题来查看所有现有的勘误信息。

著作权侵害

互联网上的版权侵害是一个跨越所有媒介的持续的问题。在Packt,我们很认真地看待版权和许可保护。如果你不经意在互联网上得到了关于我们作品的任何形式的不合法的副本,请及时给我们提供其地址或者网站名称,以便我们及时补救。

请通过copyright@packtpub.com联系我们,同时请提供涉嫌侵权材料的链接。

非常感激你帮助保护我们的作者,让我们尽力提供更有价值的内容。

问题

如果你对本书有任何疑问,可以通过 questions@packtpub.com 联系我们,我们会竭尽全力提供帮助。

第1章 准备工作环境

本章包含以下内容。

◆ 安装matplotlib、NumPy和SciPy库

◆ 安装virtualenv和virtualenvwrapper

◆ 在Mac OSX上安装matplotlib

◆ 在 Windows 上安装 matplotlib

◆ 安装Python图像处理库(Python Imaging Library,PIL)

◆ 安装requests模块

◆ 通过代码设置matplotlib的参数

◆ 为项目设置matplotlib的参数

1.1 介绍

本章向读者介绍必备的工具类库,以及如何进行安装与配置。作为本书后续部分的基础知识,掌握这部分内容十分必要。如果你没有使用Python进行数据处理、图像处理以及数据可视化的经验,建议不要跳过本章。如略过本章,在需要安装配套工具软件或需要确定工程所支持的软件版本时,可返回本章阅读相关内容。

1.2 安装matplotlib、Numpy和Scipy库

本章介绍了matplotlib及其依赖的软件在Linux平台上的几种安装方法。

1.2.1 准备工作

这里假设你已经安装了Linux 系统且安装好了Python (推荐使用Debian/Ubuntu 或RedHat/SciLinux)。在前面提到的Linux系统发行版中,Python通常是默认安装的。如果没有,使用标准的软件安装方式安装Python也是非常简便的。本书假设你安装的Python版本为2.7或以上。

几乎所有的代码均可在 Python 3.3 及以上版本的环境下工作,但是因为大部分操作系统提供的Python版本仍然是2.7(甚至是2.6),本书代码基于Python 2.7 版本。这种基于 Python 版本的区别并不大,主要是在软件包版本和部分代码上存在差别(在Python3.3以上版本,请使用range方法替换xrang方法)。

本书也假设你知道如何使用操作系统软件包管理工具进行软件包的安装,以及知道如何使用命令行终端。

构建matplotlib运行环境,需要满足相关软件依赖。

Matplotlib的构建过程依赖NumPy、libpng和freetype软件包。要从源代码构建matplotlib,必须先要安装好NumPy库。读者可以访问http://www.numpy.org/了解安装NumPy库的方法(请安装1.4或以上版本,Python 3需要NumPy 1.5或以上版本)。

NumPy库提供处理大数据集的数据结构和数学方法。诸如元组、列表或字典等Python的默认数据结构同样可以很好地支持数据的插入、删除和连接。NumPy的数据结构支持“矢量”操作,使用简便,同时具有很高的执行效率。矢量操作在实现时充分考虑了大数据的需要,基于C语言的实现方式也保证了执行效率。

基于NumPy构建的SciPy库,是Python的标准科学计算和数学计算工具包,包含了大量的专用函数和算法。而大部分函数和算法源自著名的Netlib软件仓库(参见http://www.netlib.org),实际上是使用C语言和Fortran语言实现的。

安装NumPy库的步骤如下。

1.安装Python-NumPy软件包。

$ sudo apt-get install python-numpy

2.检查软件包版本。

$ python -c 'import numpy; print numpy.__version__'

3.安装所需的库。

◆ libpng 1.2:PNG 文件处理(依赖 zlib 库)。

◆ freetype 1.4+:处理 True type 字体。

$ sudo apt-get install build-dep python-matplotlib

如果使用RedHat或基于RedHat的Linux发行版(Fedora、SciLinux或CentOS),可以使用yum工具进行安装,方法与apt-get工具类似。

$ su -c 'yum-builddep python-matplotlib'

1.2.2 操作步骤

安装matplotlib及其依赖软件的方法有很多:从源代码安装,使用预编译完成的二进制文件安装,通过操作系统软件包管理工具安装,或安装内置了matplotlib的python预打包发布版本。

使用包管理工具大概是最简单的安装方式。例如在Ubuntu系统中,在命令行终端中输入下面的命令即可。

# in your terminal, type:

$ sudo apt-get install python-numpy python-matplotlib python-scipy

如果读者期望使用最新特性,最好的选择是通过源代码进行安装。安装方式包含以下步骤:获取源代码、构建依赖库和参数配置、编译以及安装。

可以从代码托管站点www.github.com下载最新代码进行安装,操作步骤如下。

$ cd ~/Downloads/

$ wget https://github.com/downloads/matplotlib/matplotlib/matplotlib-1.2. 0.tar.gz

$ tar xzf matplotlib-1.2.0.tar.gz

$ cd matplotlib-1.2.0

$ python setup.py build

$ sudo python setup.py install

4 Python 数据可视化编程实战

下载示例代码

对于使用网站账户在 http://www.packtpub.com 上购买的所有 Packt 书籍,读者均可在网站上下载有关的代码示例。如果读者是从别处购得图书,可以访问网址(http://www.packtpub.com/support/),完成注册后,代码文件会发送到读者邮箱。

1.2.3 工作原理

从源代码安装 matplotlib, 使用了标准的 Python 发布工具 Distutils。安装过程需要提前安装依赖的软件包。关于使用标准的 Linux 包管理工具安装依赖软件的方法,可参考本节中关于准备工作的说明。

1.2.4 补充说明

根据数据可视化项目的需要,可能有必要安装额外的可选软件包。

无论你工作在什么项目上,IPython都是值得推荐的。IPython是一款交互式Python命令行工具。其提供的PyLab模式,已经导入了matplotlib库与相关软件包(例如NumPy和SciPy),可以直接使用相关库的功能。IPython 工具的安装与使用方法十分简单明了,读者可通过 IPython 的官方网站查看相关细节。

1.3 安装virtualenv和virtualenvwrapper

如果同时工作在多个项目上,或是需要在不同项目间频繁切换,将所有的软件都安装在操作系统层级上也许不是一个好主意。当需要在不同系统(产品环境)上运行软件时,这种方式会带来问题。如果到此时才发现缺少特定的软件包,或是产品环境已经安装的软件包存在版本冲突,这将是非常痛苦的。为避免这种情况发生,可以选择使用virtualenv。

virtualenv 是由 Ian Bicking 创建的开放源代码项目。通过这个项目, 开发人员可以把不同项目的工作环境隔离开,从而能够更容易地维护多种不同的软件包版本。

举例来说,Django 网站系统是基于 Django 1.1 和 Python 2.3 版本开发的,但与此同时,一个新项目要求必须基于Python2.6来开发。在笔者工作过的项目中,根据项目的需要同时使用多个版本的Python(以及相关软件包)的情况非常普遍。

virtualenv能够让我们很容易地在不同的运行环境之间切换。同时,如果需要切换到另外的机器或者需要在产品服务器(或客户的工作站主机)上部署软件, 用 virtualenv 能够很容易地重新构建相同的软件包环境。

1.3.1 准备工作

若安装virtualenv,需要用到Python和pip。Pip是安装并管理Python软件包的工具,可以用它来代替 easy install 工具。本书中大部分的软件包都是用 pip 工具进行管理的。只需在终端中以root身份执行如下命令,就可以很容易地完成pip的安装。

# easy_install pip

virtualenv 本身已经相当不错了,然而如果配合 virtualenvwrapper,一切变得更加简单,并且组织多个虚拟环境的工作也会更加容易。virtualenvwrapper 的功能请参考 http://virtualenvwrapper. readthedocs.org/en/latest/#features。

1.3.2 操作步骤

安装virtualenv和virtualenvwrapper工具的步骤如下。

1.安装virtualenv和virtualenvwrapper。

$ sudo pip virtualenv

$ sudo pip virtualenvwrapper

# 创建保存虚拟环境的目录,并使用 export 导出为环境变量。

$ export VIRTENV=~/.virtualenvs

$ mkdir -p $VIRTENV

# 使用 source 命令调用(执行)shell 脚本来激活包装器

$ source /usr/local/bin/virtualenvwrapper.sh

# 创建一个虚拟环境

$ mkvirtualenv virt1

2.在virt1环境中安装matplotlib。

(virt1)user1:~$ pip install matplotlib

3.很有可能需要把以下代码添加到~/.bashrc中。

source /usr/loca/bin/virtualenvwrapper.sh

下面是一些有用和频繁使用的命令。

◆ mkvirtualenv ENV: 创建名为 ENV 的虚拟环境并激活。

◆ workon ENV: 激活先前创建的 ENV 虚拟环境。

◆ deactivate: 退出当前虚拟环境。

1.4 在Mac OS X上安装matplotlib

在 Mac OS X 上获取 matplotlib 最简便的方式是使用预打包的 python 发布版本,例如Enthought Python Distribution (EPD)。读者可以直接访问 EPD 网站,下载安装操作系统对应的最新稳定版。

倘若EPD软件不满足要求,或者因为其他一些原因(如版本问题)而无法使用,也可以用手动(麻烦点)的方式安装Python、matplotlib和依赖软件。

1.4.1 准备工作

对于Apple在操作系统中没有安装的软件来说,Homebrew项目可以使安装过程更容易。实际上,Homebrew是基于Ruby和Git的,可以被自动下载和安装。软件安装顺序为:首先安装 Homebrew,之后安装 Python,随后安装诸如 virtualenv 的工具软件,接下来安装matplotlib的依赖(NumPy和SciPy),最后安装matplotlib。接下来就开始吧。

1.4.2 操作步骤

1.在终端中输入并执行下面的命令。

ruby <(curl -fsSkL raw.github.com/mxcl/homebrew/go)

命令执行完成后,可以尝试用 brew update 或 brew doctor 命令来检查 brew 是否能够正常工作。

2.然后,将Homebrew目录添加到系统path环境变量中。这样,使用Homebrew安装的软件包能够获得比其他版本更高的优先级。打开~/.bash_profile文件(或者/Users/[your-user-name]/.bash_profile)并在文件末尾添加以下代码。

export PATH=/usr/local/bin:$PATH

3.重新启动命令行终端使其加载新的 path 环境变量。之后,下面一行简单的代码就可以完成Python的安装。

brew install python --framework –universal

本命令同时也将安装Python所需的其他软件。

4.更新path环境变量(添加到同一行)。

export PATH=/usr/local/share/python:/usr/local/bin:$PATH

5.在命令行输入 python –version,检查 python 是否安装成功。

正常的话,会能够看到Python版本信息为2.7.3。

6.pip应该也已经安装完毕。如果还没有,可使用easy_install安装pip。

$ easy_install pip

7.这时,任何所需软件包的安装过程就变得非常简单了。例如,安装 virtualenv 和virtualenvwrapper。

pip install virtualenv

pip install virtualenvwrapper

8.是时候向一直以来的目标迈进了——安装matplotlib。

pip install numpy

brew install gfortran

pip install scipy

Mountain Lion 的用户需要安装 SciPy 的开发版(0.11),命令如下。

pip install -e git+https://github.com/scipy/scipy#egg=scipy- dev

9.检查安装是否成功。启动Python并执行以下命令。

import numpy

print numpy.__version__

import scipy

print scipy.__version__

quit()

10.安装matplotlib。

pip install matplotlib

1.5 在Windows上安装matplotlib

在本节中,我们将演示如何安装Python和matplotlib。假设系统中没有预先安装Python。

1.5.1 准备工作

在Windows上安装matplotlib有两种方式。较简单的方式是安装预打包的Python环境,如EPD、Anaconda和Python(x,y)。这是本书推荐的安装方式,尤其对于初学者来说更是如此。

第二种方式,是使用预编译的二进制文件来安装matplotlib和依赖软件包。需要注意安装的NumPy和SciPy的版本,因为并非所有的版本都与最新版matplotlib二进制文件相互兼容,这势必会给整个安装过程带来一些困难。这种安装方法也有自身的优势。如果想要获取最新功能,即使功能还未正式发布,仍然能够通过编译matplotlib或某软件库的某个特定版本来使用它。

1.5.2 操作步骤

要安装免费或商业Python科学发布版,按照项目网站上提供的步骤可以很容易安装成功,这也是推荐使用的方式。

如果单纯使用matplotlib,不期望面对Python和依赖软件包版本所带来的困扰,可以考虑使用 Enthought Python Distribution(EPD)发布版。使用 matplotlib 所需的预打包库和所有必须的依赖软件(SciPy、NumPy、IPython以及更多的其他软件包),均已包含在EPD发布版中。

matplotlib 以及与本书内容相关的软件,都可以使用常规的 Windows Installer 安装文件(*.exe)方式进行安装。

Python(x,y)(http://code.google.com/p/pythonxy/)是针对 Windows 32 位系统的免费科学计算项目,其中包含了 matplotlib 需要使用的依赖文件,它是在 Windows 系统上安装matplotlib 的一种非常简单(而且是免费的)的方式。因为 Python(x,y)和 Python 模块安装器相互兼容,可以很容易地在Python(x,y)基础上扩展安装其他Python库。在安装Python(x,y)之前,系统应该没有安装Python。

下面简短地说明一下如何使用预编译的Python、NumPy、SciPy和matplotlib二进制文件进行matplotlib的安装。首先,下载官方的MSI安装文件安装对应平台(x86或x86-64)的标准Python程序。之后,下载NumPy和SciPy的官方二进制文件并安装它们。在正确安装NumPy和SciPy之后,就可以下载最新稳定版matplotlib二进制安装文件并按照官方说明进行安装了。

1.5.3 补充说明

请注意,在Windows安装文件中matplotlib的示例相当有限。如果想尝试使用示例程序,可以下载并参考matplotlib源文件包中的examples子目录。

1.6 安装图像处理工具:Python图像库(PIL)

Python图像库(PIL)为Python提供了图像处理能力。PIL支持的文件格式相当广泛,在图像处理领域提供了相当强大的功能。

快速数据访问、点运算(point operations)、滤波(filtering)、图像缩放、旋转、任意仿射转换(arbitrary affine transforms)是 PIL 中一些应用非常广泛的特性。例如,图像的统计数据即可通过histogram方法获得。

PIL 同样可以应用在其他方面,如批量处理、图像压缩、生成缩略图、图像格式转换以及图像打印。

PIL 可以读取多种图像格式,而图像写入支持的格式范围限定在图像交换和展示方面最通用的格式(有意为之)。

1.6.1 操作步骤

最容易也是最值得推荐的方式,是通过操作系统平台的包管理工具进行安装。

在Debian/Ubuntu系统中安装的命令如下。

$ sudo apt-get build-dep python-imaging

$ sudo pip install http://effbot.org/downloads/Imaging-1.1.7.tar.gz

1.6.2 安装过程说明

我们通过apt-get系统工具安装PIL所需的所有依赖软件,并通过pip安装PIL的最新稳定版本。一些老版本的Ubuntu系统通常不会提供PIL的最新发布版本。

在RedHat/SciLinux系统中,安装命令如下。

# yum install python-imaging

# yum install freetype-devel

# pip install PIL

1.6.3 补充说明

有一个专门针对 PIL 编写的在线手册。读者可以访问 http://www.pythonware. com/library/pil/handbook/index.htm 进行阅读,或是下载 PDF 版本:http://www.pythonware. com/media/data/pil-handbook.pdf。

Pillow 是一个 PIL 分支,它的主要目的是解决安装过程中的一些问题。Pillow 很容易安装,其网址为http://pypi.python.org/pypi/Pillow。

在Windows平台上,也可使用二进制安装文件安装PIL。从http://www.pythonware. com/products/pil/下载.exe安装文件,执行该文件将安装 PIL 到 Python 的 site-packages目录。

如果需要在虚拟环境下使用 PIL,可手动将 PIL.pth 文件和位于 C:\Python27\Lib\site-packages下的PIL目录复制到virtualenv的site-packages目录下。

1.7 安装requests模块

我们需要的大部分数据都可以通过HTTP或类似协议获得,因此我们需要一些工具来实现数据访问。Python的requests库能让这部分工作变得轻松起来。

虽然Python提供的urllib2模块提供了访问远程资源的能力以及对HTTP协议的支持,但使用该模块完成基础任务的工作量还是很大的。

Request模块提供新的API,减轻了使用Web服务的痛苦,使其变得更直接。Requests封装了很多 HTTP 1.1 的内容,仅在需要实现非默认行为的情况下才需要暴露相关内容。

1.7.1 操作步骤

安装requests模块最好的方式是使用pip。安装命令如下。

$ pip install requests

也可以在virtualenv虚拟环境中执行安装命令,如果并不是所有项目都需要requests,或是不同的项目需要使用不同版本的requests。

为了更快地理解requests的功能,下面是一个使用requests的小例子。

import requests

r = requests.get('http://github.com/timeline.json')

print r.content

1.7.2 requests 使用说明

在本例中,我们向 www.github.com 站点的 URI 发送 HTTP GET 请求,以 JSON格式返回了 GitHub 网站的活动时间表(也可以通过访问 https://github.com/timeline 得到HTML版本的活动时间表)。在成功读取HTTP响应后,对象r包含了HTTP响应内容以及其他属性信息(HTTP状态码、cookies、HTTP头元数据,甚至包括当前响应所对应的请求信息)。

1.8 在代码中配置matplotlib参数

matplotlib库提供了强大的绘图功能,是本书用的最多的Python库。在其配置文件即.rc文件中,已经为大部分属性设定了默认值。本节会介绍如何通过应用程序代码修改matplotlib的相关属性值。

1.8.1 准备工作

如前所述,matplotlib配置信息是从配置文件读取的。在配置文件中可以为matplotlib的几乎所有的属性指定永久有效的默认值。

1.8.2 操作步骤

在代码执行过程中,有两种方式更改运行参数:使用参数字典(rcParams)或调用matplotlib.rc()命令。第一种方式中,可以通过rcParams字典访问并修改所有已经加载的配置项;第二种方式中,可以通过向 matlotlib.rc()传入属性的关键字元组来修改配置项。

如果需要重置动态修改后的配置参数,可以调用matplotlib.rcdefaults()将配置重置为标准设置。

下面两段代码演示了之前介绍的功能。

使用matplotlib.rcParams的例子。

import matplotlib as mp

mpl.rcParams['lines.linewidth'] = 2

mpl.rcParams['lines.color'] = 'r'

使用matplotlib.rc()函数调用的例子。

import matplotlib as mpl

mpl.rc('lines', linewidth=2, color='r')

上面两个例子具有相同的语义。第二个例子中,我们设定后续的所有图形使用的线条宽度为2个点。第一个例子中的最后一条语句表明,语句之后的所有线条的颜色均为红色,除非用本地设置覆盖它,请看下面的例子。

import matplotlib.pyplot as plt

import numpy as np

t = np.arange(0.0, 1.0, 0.01)

s = np.sin(2 * np.pi * t)

# make line red

plt.rcParams['lines.color'] = 'r'

plt.plot(t,s)

c = np.cos(2 * np.pi * t)

# make line thick

plt.rcParams['lines.linewidth'] = '3'

plt.plot(t,c)

plt.show()

1.8.3 代码解析

首先,为了绘制正弦、余弦曲线,需要导入matplotlib.pyplot和NumPy模块。在绘制第一个图像之前,通过 plt.rcParams['lines.color']= 'r'语句显式地设置线条颜色为红色;接下来,对于第二个图像(余弦曲线),通过语句plt.rcParams['lines. linewidth'] = '3'显式地设定线宽为 3 个点。

如果需要重置设置,需要调用matplotlib.rcdefaults()方法。

1.9 为项目设置matplotlib参数

本节介绍matplotlib使用的各种配置文件的位置,以及使用这些配置文件的意义。同时还将介绍配置文件中的具体配置项。

1.9.1 准备工作

如果不想在每次使用 matplotlib 时都在代码开始部分进行配置(像前一节我们做的那样),就需要为不同的项目设定不同的默认配置项。本节将介绍如何做到这一点。这种配置方式使得配置项与代码分离,从而使代码更加整洁。此外,你可以很容易在同事间甚至项目间分享配置模板。

1.9.2 配置方法

假设一个项目对于matplotlib的特性参数总会设置相同的值,就没有必要在每次编写新的绘图代码时都进行相同的配置。取而代之的,应该是在代码之外,使用一个永久的文件设定matplotlib参数默认值。

通过 matplotlibrc 来配置文件,matplotlib 提供了对这种配置方式的支持。在matplotlibrc文件中包含了绝大部分可以变更的属性。

1.9.3 配置过程说明

配置文件可能存在于三个不同的位置,而它们的位置决定了它们的应用范围。这三个位置分别说明如下。

◆ 当前工作目录:即代码运行的目录。在当前目录下,可以为目录所包含的当前项目代码定制matplotlib配置项。配置文件的文件名是matplotlibrc。

◆ 用户级.matplotlib/matplotlibrc 文件(Per user .matplotlib/matplotlibrc):通常是在用户的$HOME 目录下(在 Windows 系统中,也就是 Documents and Settings 目录)。可以用 matplotlib.get_configdir()命令来找到当前用户的配置文件目录。请参考随后的命令示例。

◆ 安装级配置文件(Per installation configuration file):通常在python的site-packages目录下。这是系统级配置,不过在每次重新安装matplotlib后,配置文件会被覆盖。因此如果希望保持持久有效的配置,最好选择在用户级配置文件中进行设置。对于笔者来说,目前对本配置文件的最佳应用方式,是将其作为默认配置模板。如果在用户级配置文件已经比较混乱,或者需要为新项目做全新配置时,可以基于该配置文件进行设置。

在shell中运行下面的命令,即可打印出配置文件目录的位置:

$ python -c 'import matplotlib as mpl; print mpl.get_configdir()'

配置文件包括以下配置项。

◆ axes:设置坐标轴边界和表面的颜色、坐标刻度值大小和网格的显示。

◆ backend:设置目标输出 TkAgg和 GTKAgg。

◆ figure:控制 dpi、边界颜色、图形大小和子区(subplot)设置。

◆ font:字体集(font family)、字体大小和样式设置。

◆ grid:设置网格颜色和线型。

◆ legend:设置图例和其中文本的显示。

◆ line:设置线条(颜色、线型、宽度等)和标记。

◆ patch:是填充 2D 空间的图形对象,如多边形和圆。控制线宽、颜色和抗锯齿设置等。

◆ savefig:可以对保存的图形进行单独设置。例如,设置渲染的文件的背景为白色。

◆ text:设置字体颜色、文本解析(纯文本或 latex 标记)等。

◆ verbose:设置 matplotlib 在执行期间信息输出,如 silent、helpful、debug 和debug-annoying。

◆ xticks 和 yticks:为 x、y 轴的主刻度和次刻度设置颜色、大小、方向,以及标签大小。

1.9.4 补充说明

如果你想了解前面提到的(和我们没有提到的)每个设置的详细信息,最好的方式是访问 matplotlib 项目的网站,那里提供了最新的 API 文档。如果需要获得进一步帮助,可以在用户和开发邮件组留言。本书最后还提供了一些有用的在线资源。

第5章 创建3D可视化图表

本章将学习以下内容。

◆ 创建 3D 柱状图

◆ 创建 3D 直方图

◆ 在 matplotlib 中创建动画

◆ 用 OpenGL 制作动画

5.1 简介

3D可视化有时候是很有效的,有时候也是不可避免的。在这里我们将展示一些例子,这些例子将满足一些最常用的需求。

本章将会介绍并讲解一些3D可视化的话题。

5.2 创建 3D 柱状图

虽然matplotlib主要专注于绘图,并且主要是二维的图形,但是它也有一些不同的扩展,能让我们在地理图上绘图,让我们把Excel和3D图表结合起来。在matplotlib的世界里,这些扩展叫做工具包(toolkits)。工具包是一些关注在某个话题(如3D绘图)的特定函数的集合。

比较流行的工具包有 Basemap、GTK 工具、Excel 工具、Natgrid、AxesGrid 和 mplot3d。

本节将探索关于 mplot3d 的更多功能。mpl_toolkits.mplot3工具包提供了一些基本的3D绘图功能,其支持的图表类型包括散点图(scatter)、曲面图(surf)、线图(line)和网格图(mesh)。虽然mplot3d不是一个最好的3D图形绘制库,但是它是伴随着matplotlib产生的,因此我们对其接口已经很熟悉了。

5.2.1 准备工作

基本来讲,我们仍然需要创建一个图表并把想要的坐标轴添加到上面。但不同的是我们为图表指定的是3D视图,并且添加的坐标轴是Axes3D。

现在,我们可以使用几乎相同的函数来绘图了。当然,函数的参数是不同的,需要为3个坐标轴提供数据。

例如,我们要为函数 mpl_toolkits.mplot3d.Axes3D.plot 指定 xs、ys、zs 和zdir 参数。其他的参数则直接传给 matplotlib.axes.Axes.plot。下面来解释一下这些特定的参数。

1.xs和ys:x轴和y轴坐标。

2.zs:这是z轴的坐标值,可以是所有点对应一个值,或者是每个点对应一个值。

3.zdir:决定哪个坐标轴作为z轴的维度(通常是zs,但是也可以是xs或者ys)。

模块 mpl_toolkits.mplot3d.art3d包含了 3D artist 代码和将 2Dartists转化为3D版本的函数。在该模块中有一个rotate_axes方法,该方法可以被添加到Axes3D中来对坐标重新排序,这样坐标轴就与zdir一起旋转了。zdir默认值为z。在坐标轴前加一个'-'会进行反转转换,这样一来,zdir的值就可以是x、-x、y、-y、z或者-z。

5.2.2 操作步骤

以下代码演示了我们所解释的概念。

import random

import numpy as np

import matplotlib as mpl

import matplotlib.pyplot as plt

import matplotlib.dates as mdates

from mpl_toolkits.mplot3d import Axes3D

mpl.rcParams['font.size'] = 10

fig = plt.figure()

ax = fig.add_subplot(111, projection='3d')

for z in [2011, 2012, 2013, 2014]:

xs = xrange(1,13)

ys = 1000 * np.random.rand(12)

color = plt.cm.Set2(random.choice(xrange(plt.cm.Set2.N)))

ax.bar(xs, ys, zs=z, zdir='y', color=color, alpha=0.8)

ax.xaxis.set_major_locator(mpl.ticker.FixedLocator(xs))

ax.yaxis.set_major_locator(mpl.ticker.FixedLocator(ys))

ax.set_xlabel('Month')

ax.set_ylabel('Year')

ax.set_zlabel('Sales Net [usd]')

plt.show()

上述代码生成如图5-1所示的图表。

5.2.3 工作原理

我们需要像在 2D 世界中那样做相同的准备工作。不同的是,在这里需要指定后端(backend)的种类。然后生成了一些随机数据,例如4年的销售额(2011-2014)。

我们需要为3D坐标轴指定相同的Z值。

从颜色映射集合中随机选择一种颜色,然后把它和每一个Z-order集合的xs、ys对关联起来。最后,用xs、ys对渲染出柱状条序列。

5.2.4 补充说明

其他的一些matplotlib的2D绘图函数在这里也是可以用的,例如scatter()和plot()有着相似的接口,但有额外的点标记大小参数。我们对contour、contourf和bar也非常熟悉。

仅在 3D 中出现的新图表类型有线框图(wireframe)、曲面图(surface)和三翼面图(tri-surface)。

在下面的示例代码中,我们绘制了著名的Pringle函数的三翼面图,数学专业上的叫法是双曲面抛物线(hyperbolic paraboloid)。

from mpl_toolkits.mplot3d import Axes3D

from matplotlib import cm

import matplotlib.pyplot as plt

import numpy as np

n_angles = 36

n_radii = 8

# An array of radii

# Does not include radius r=0, this is to eliminate duplicate points

radii = np.linspace(0.125, 1.0, n_radii)

# An array of angles

angles = np.linspace(0, 2 * np.pi, n_angles, endpoint=False)

# Repeat all angles for each radius

angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)

# Convert polar (radii, angles) coords to cartesian (x, y) coords

# (0, 0) is added here. There are no duplicate points in the (x, y)

plane

x = np.append(0, (radii * np.cos(angles)).flatten())

y = np.append(0, (radii * np.sin(angles)).flatten())

# Pringle surface

z = np.sin(-x * y)

fig = plt.figure()

ax = fig.gca(projection='3d')

ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.2)

plt.show()

上面的代码生成如图5-2所示的图形。

5.3 创建 3D 直方图

像3D柱状图一样,我们可能想创建3D直方图。3D直方图可以用来很容易地识别3个独立变量之间的相关性。可以用它们来从图像中提取信息,其中第三个维度可以是所分析的图像的(x, y)空间通道的强度。

本节将学习如何创建3D直方图。

5.3.1 准备工作

回顾一下,直方图表示的是一些值在特定列(通常叫做“bin”)中的发生率。那么,三维直方图表示的是在一个网格中的发生率。网格是矩形的,表示的是在两列中关于两个变量的发生率。

5.3.2 操作步骤

在这个计算过程中,我们将进行如下操作。

1.使用Numpy,因为其拥有计算两个变量的直方图的函数。

2.用正态分布函数生成x和y,但是给它们提供不同的参数,以便能区分结果直方图的相互关系。

3.用相同的数据集合绘制散点图,展示散点图和3D直方图显示上的差异。

下面是实现上述步骤的代码。

import numpy as np

import matplotlib.pyplot as plt

import matplotlib as mpl

from mpl_toolkits.mplot3d import Axes3D

mpl.rcParams['font.size'] = 10

samples = 25

x = np.random.normal(5, 1, samples)

y = np.random.normal(3, .5, samples)

fig = plt.figure()

ax = fig.add_subplot(211, projection='3d')

# compute two-dimensional histogram

hist, xedges, yedges = np.histogram2d(x, y, bins=10)

# compute location of the x,y bar positions

elements = (len(xedges) - 1) * (len(yedges) - 1)

xpos, ypos = np.meshgrid(xedges[:-1]+.25, yedges[:-1]+.25)

xpos = xpos.flatten()

ypos = ypos.flatten()

zpos = np.zeros(elements)

# make every bar the same width in base

dx = .1 * np.ones_like(zpos)

dy = dx.copy()

# this defines the height of the bar

dz = hist.flatten()

ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', alpha=0.4)

ax.set_xlabel('X Axis')

ax.set_ylabel('Y Axis')

ax.set_zlabel('Z Axis')

# plot the same x,y correlation in scatter plot

# for comparison

ax2 = fig.add_subplot(212)

ax2.scatter(x, y)

ax2.set_xlabel('X Axis')

ax2.set_ylabel('Y Axis')

plt.show()

上述代码生成如图5-3所示的图形。

5.3.3 工作原理

我们用 np.histogram2d 生成了一个直方图,该方法返回了直方图(hist)、x bin边界和 y bin边界。

bar3d 函数需要 x, y 空间的坐标,因此需要计算出一般的矩阵坐标,对此我们使用np.meshgrid函数把x和y位置的向量合并到2D空间网格中(矩阵)。我们可以使用它在xy平面位置上绘制矩形条。

变量dx和dy表示每一个矩形条底部的宽度,我们想把它设置为常数,因此我们为xy平面的每一个位置给定的值为 0.1 个点的宽度。

z轴上的值(dz)实际上是计算机直方图(在变量hist中),它表示在一个特定的bin中一般的x和y样本的个数。

接下来在散点图(图5-3)中显示了一个2D坐标轴,也呈现了两组相似但起始参数不同的分布间的相互关系。

有时候,3D给予我们更多的信息,并以一个更好的方式让我们来理解数据所包含的内容。然而在更多情况下,3D可视化比2D更加让人感到迷惑,所以在舍弃2D选择3D之前最好慎重考虑。

5.4 在matplotlib中创建动画

本节将学习如何让图表动起来。有时候,在解释当我们改变变量值时会发生什么情况的时候,动画有着更强的描述性。主要函数库的动画能力有限,但通常已足够了。接下来将解释如何使用它们。

5.4.1 准备工作

从 1.1 版本开始,一个动画框架被添加到了标准 matplotlib 库中,该框架主要的类是matplotlib.animation.Animation。这个类是一个基类,它可以针对不同的行为被子类化。实际上,该框架已经提供了几个类:TimedAnimation、ArtistAnimation 和FuncAnimation。表5-1给出了这几个类的描述。

为了能把动画存储到一个视频文件中,必须安装ffmpeg或者mencoder。这些包的安装根据我们所使用的操作系统的不同以及不同版本间的差别会有所不同,因此我们把它留给亲爱的读者去Google一下有效的相关信息。

5.4.2 操作步骤

下述代码演示了一些matplotlib动画。

import numpy as np

from matplotlib import pyplot as plt

from matplotlib import animation

fig = plt.figure()

ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))

line, = ax.plot([], [], lw=2)

def init():

"""Clears current frame."""

line.set_data([], [])

return line,

def animate(i):

"""Draw figure.

@param i: Frame counter

@type i: int

"""

x = np.linspace(0, 2, 1000)

y = np.sin(2 * np.pi * (x - 0.01 * i)) * np.cos(22 * np.pi * (x - 0.01 * i))

line.set_data(x, y)

return line,

# This call puts the work in motion

# connecting init and animate functions and figure we want to draw

animator = animation.FuncAnimation(fig, animate, init_func=init,

frames=200, interval=20, blit=True)

# This call creates the video file.

# Temporary, every frame is saved as PNG file

# and later processed by ffmpeg encoder into MPEG4 file

# we can pass various arguments to ffmpeg via extra_args

animator.save('basic_animation.mp4', fps=30,

extra_args=['-vcodec', 'libx264'],

writer='ffmpeg_file')

plt.show()

本代码将在执行该文件的文件夹中创建文件 basic_animation.mp4,同时显示一个有动画的图形窗口。该视频文件可以用大多数支持MPEG-4格式的视频播放器打开。图形(帧)看上去如图5-4所示。

5.4.3 工作原理

上面例子中最重要的几个函数是 init()、animate()和 save()。首先,通过向FuncAnimate[1]传入两个回调函数,init和animator。然后,调用它的save()方法保存视频文件。表5-2是关于每一个函数更多的细节内容。

5.4.4 补充说明

matplotlib.animation.ArtistAnimation的用法和FuncAnimation不同,我们必须事先绘制出每一个artist,然后用所有artist的不同帧来实例化ArtistAnimation类。Artist动画是对matplotlib.animation.TimedAnimation类的一种封装,每N毫秒绘制一次帧,因此它支持基于时间的动画。

不幸的是,对于 Mac OS X 的用户来说,动画框架在该平台上却让人很苦恼,有时候甚至不能工作。这在matplotlib未来的版本中会有所改进。

5.5 用OpenGL制作动画

使用OpenGL的动机来源于CPU处理能力的限制,限制体现在当我们面临一项要可视化成千上万个数据点的工作,并且要求其快速执行(有时甚至是实时的)的时候。

现代计算机拥有强大的GPU用于加速与可视化相关的计算(比如游戏)。它们没有理由不能用于科学相关的可视化。

实际上,编写硬件加速的软件至少有一个缺点。就硬件的依赖而言,现代图形卡要求有专有的驱动,有时候驱动在目标平台/机器(例如用户的笔记本)上是无法使用的;即使是可用的,有时候你也不想呆在那花大把的时间去安装驱动所依赖的软件,相反,你想把时间花费在展示你的发现,并演示你的研究成果上。虽然这并不会成为编写硬件加速软件的障碍,但是你还是需要考虑一下这件事情,并且衡量一下在项目中引入这个复杂性的成本和收益。

解释完缺点后,我们可以对硬件加速可视化说“是”,可以对OpenGL,这一图形加速的工业标准说“是”。

我们将使用OpenGL来完成本节的内容,因为它是跨平台的,因此所有的例子应该在Linux、Mac 或者 Windows 上都是工作的,就像我们所演示的那样。这里假定你已经安装了所需的硬件和操作系统级别的驱动。

5.5.1 准备工作

如果你从来没有使用过 OpenGL,现在我们将做一个快速的介绍来帮助你理解。但是要真正的了解OpenGL,至少要阅读并理解一整本书。OpenGL是一个规范,而不是一个实现,因此OpenGL本身并没有任何实现代码,所有的实现是遵循该规范而开发的库。这些库是跟随你的操作系统,或者由如NVIDIA或者AMD/ATI等不同的显卡厂商发布的。

此外,OpenGL只关注图形渲染而不是动画、定时和其他复杂的事情,这些事情是留给其他库来完成的。

OpenGL动画基础

因为OpenGL是一个图形渲染库,所以它不知道我们在屏幕上绘制的是什么。它不关心我们画的是否是一只猫、一个球,或者一条线,还是所有这些对象。因此,要移动一个已经渲染的对象,需要清除并重绘整个图像。为了让某个物体动起来,我们需要很快地循环绘制和重绘所有内容,并把它显示给用户,这样用户就认为他/她正在观看一个动画。

在机器上安装 OpenGL 是一件和平台相关的过程。在 Mac OS X 上,OpenGL 的安装通过系统升级来完成,但是开发库(所谓的“头文件”)是Xcode开发包的一部分。

在Windows系统上,最好的方式是安装电脑的显卡厂商的最新显卡驱动程序。OpenGL可能并不需要它们就可以工作,但那样的话你就很可能失去了原版驱动程序的最新特性。

在 Linux 平台上,如果你不反对安装闭源软件,在操作系统发行版自身的软件管理器中,或者显卡厂商网站上的二进制安装文件,都提供了可供下载的特定厂商的驱动。Mesa3D几乎一直都是OpenGL的标准实现,它也是最有名的OpenGL实现,使用Xorg来为Linux、FreeBSD和类似操作系统的OpenGL提供支持。

基本上,在Debian/Ubuntu系统中,应当安装下列软件包及其依赖。

$ sudo apt-get install libgl1-mesa-dev libgl-mesa-dri

然后,你就可以使用一些开发库和/或者框架来实际地编写OpenGL支持的应用程序了。

我们在这里只关注Python中的OpenGL绘图,因此我们将回顾在Python中使用最多的一些构建在OpenGL之上的库和框架。我们会提到matplotlib及其当前和将来对OpenGL的支持。

◆ Mayavi:这是一个专门用于 3D 的库。

◆ Pyglet:这是一个纯 Python 的图形库。

◆ Glumpy:这是一个构建在 Numpy 之上的快速图形渲染库。

◆ Pyglet 和 OpenGL:这是用来可视化大数据(百万级数据点)的。

5.5.2 操作步骤

专业化的项目Mayavi是一个功能全面的3D图形库,它主要用于高级3D渲染。它包含在已经提到的 Python 包中,如 EPD(虽然没有免费许可)。这也是在 Windows 和 Mac OS X操作系统上的推荐安装方式。在Linux平台上,也可以通过pip轻松地安装,代码如下。

$ pip install mayavi

Mayavi 可以作为一个开发库/框架,或者一个应用程序来使用。Mayavi 应用程序包含了一个可视化编辑器,可以用于简单的数据研究和一些交互可视化。

作为一个图形库,Mayavi的用法和matplotlib相似。它可以从一个脚本接口中,或者作为一个完全的面向对象的库来使用。Mayavi的大多数接口在mlab模块中,可以使用它们来制作动画。例如,可以像下面代码那样来完成一个简单的Mayavi动画。

import numpy

from mayavi.mlab import *

# Produce some nice data.

n_mer, n_long = 6, 11

pi = numpy.pi

dphi = pi/1000.0

phi = numpy.arange(0.0, 2*pi + 0.5*dphi, dphi, 'd')

mu = phi*n_mer

x = numpy.cos(mu)*(1+numpy.cos(n_long*mu/n_mer)*0.5)

y = numpy.sin(mu)*(1+numpy.cos(n_long*mu/n_mer)*0.5)

z = numpy.sin(n_long*mu/n_mer)*0.5

# View it.

l = plot3d(x, y, z, numpy.sin(mu), tube_radius=0.025,

colormap='Spectral')

# Now animate the data.

ms = l.mlab_source

for i in range(100):

x = numpy.cos(mu)*(1+numpy.cos(n_long*mu/n_mer +

numpy.pi*(i+1)/5.)*0.5)

scalars = numpy.sin(mu + numpy.pi*(i+1)/5)

ms.set(x=x, scalars=scalars)

上述代码将生成如图5-5所示的带旋转图形的窗口。

5.5.3 工作原理

我们生成了数据集合,并创建了x、y和z三个函数。这些函数被用在plot3d函数中作为图形的起始位置。

然后,导入 mlab_source 对象,以便能在点和标量的级别上操作图形。然后使用这个特性在循环中设置特定的点和标量来创建一个100帧的旋转动画。

5.5.4 补充说明

如果你想实验更多的内容,最简单的方式是打开IPython,导入myayvi.lab,并运行一些名字为test_*的函数。

为了了解到底发生了什么,你可以借助IPython的功能来检查和研究Python源码,像下面代码显示的这样。

In [1]: import mayavi.mlab

In [2]: mayavi.mlab.test_simple_surf??

Type:  function

String Form:<function test_simple_surf at 0x641b410>

File:  /usr/lib/python2.7/dist-packages/mayavi/tools/helper_

functions.py

Definition: mayavi.mlab.test_simple_surf()

Source:

def test_simple_surf():

"""Test Surf with a simple collection of points."""

x, y = numpy.mgrid[0:3:1,0:3:1]

return surf(x, y, numpy.asarray(x, 'd'))

这里,我们看到如何通过在函数名后面添加两个问号(“??”)让IPython找到函数的源码并显示。这是一个真实的探索性计算,经常在可视化社区中被使用,因为它是了解数据和代码的一个快速的方式。

Pyglet快速入门

Pyglet是另一个著名的Python库,可以让编写图形和与窗口相关的应用程序变得轻松起来。它通过模块pyglet.gl来支持OpenGL,但是为了能使用Pyglet的威力你不必直接使用这个模块。通过pyglet.graphics来使用它是最方便的用法。

Pyglet采用了一种和Mayavi不同的方式。它没有可视化的IDE,你要负责从创建窗口,到发出一个低级别的 OpenGL 调用来配置 OpenGL 上下文环境的所有工作。它有时比Mayavi慢,但是你所获得的是控制应用程序的每个部分的能力。这有时候也意味着会投入更多的工作时间,但是通常来讲,它也意味着你的应用程序有更高的质量和性能。

可以通过下面的代码来得到一个简单的应用程序(图像查看器)。

import pyglet

window = pyglet.window.Window()

image = pyglet.resource.image('kitten.jpg')

@window.event

def on_draw():

window.clear()

image.blit(0, 0)

pyglet.app.run()

上述代码创建了一个窗口,加载了一幅图像,并指定了当我们绘制一个窗口对象时所发生的事件(换言之,我们为 on_draw事件定义了一个事件处理器)。最后,运行我们的程序(piglet.app.run())。

在实现的内部,程序使用OpenGL在窗口上进行绘制。此接口可以从pyglet.gl模块获得。然而直接使用它是不高效的,因此pyglet在pyglet.graphics中提供了一个更简单的接口,在这个接口内部使用了顶点数组(vertex arrays)和缓冲区(buffers)。

Glumpy快速入门

Glumpy是一个OpenGL+NumPy库,它用OpenGL来进行快速Numpy可视化。它是一个由 Nicolas Rougier 启动的开源项目,致力于高效可视化。为了使用它,我们需要 Python OpenGL绑定(bindings)、SciPy,当然还有Glumpy。安装命令如下。

sudo apt-get install python-opengl

sudo pip install scipy

sudo pip install glumpy

Glumpy 使用 OpenGL 纹理(textures)来表示阵列,因为这恐怕是在现代图形硬件上最快的可视化方法了。

Pyprocessing 简介

Pyprocessing和Processing(http://processing.org)的工作方式极其相似。Pyprocessing中的大多数函数和Processing函数是相同的。如果你熟悉Processing和Python,你就已经知道了编写Pyprocessing程序所需的几乎所有知识。为了使用它,我们唯一需要做的事情是导入pyprocessing包,用Pyprocessing函数和数据结构来编写剩余的代码,然后调用run()函数来执行。

有很多关于 OpenGL 以及如何在 C/C++或者任何其他语言 binding 中使用它的免费教程。在 OpenGL 官方 wiki 上提供了一个清单,地址为 http://www.opengl. org/wiki/Getting_started#Tutorials_and_How_To_Guides。

总之,还有许多处理Python、OpenGL和3D可视化的项目,其中有一些比较年轻,有一些已经不再维护了,但是如果你发现有项目应该被提到,请告诉我们。

注释

[1]. 应为 FuncAnimation。

相关图书

深度学习的数学——使用Python语言
深度学习的数学——使用Python语言
动手学自然语言处理
动手学自然语言处理
Web应用安全
Web应用安全
Python高性能编程(第2版)
Python高性能编程(第2版)
图像处理与计算机视觉实践——基于OpenCV和Python
图像处理与计算机视觉实践——基于OpenCV和Python
Python数据科学实战
Python数据科学实战

相关文章

相关课程