Matplotlib 用户指南 User Guide
matplotlib-user-guide
matplotlib-user-guide
User Manual:
Open the PDF directly: View PDF .
Page Count: 228 [warning: Documents this large are best viewed by clicking the View PDF Link!]

1.1
1.2
1.3
1.4
1.4.1
1.4.2
1.4.3
1.4.4
1.4.5
1.4.6
1.4.7
1.4.8
1.4.9
1.5
1.5.1
1.5.2
1.5.3
1.5.4
1.5.5
1.5.6
1.5.7
1.5.8
1.6
1.6.1
1.6.2
1.6.3
1.7
1.8
1.8.1
1.8.2
1.8.3
1.9
1.9.1
1.9.2
1.10
目錄
Matplotlib用户指南
简介
安装
教程
Pyplot教程
图像教程
使用GridSpec自定义子图位置
密致布局教程
艺术家教程
图例指南
变换教程
路径教程
路径效果指南
处理文本
引言
基本的文本命令
文本属性及布局
默认字体
标注
编写数学表达式
使用LaTeX渲染文本
XeLaTeX/LuaLaTeX设置
颜色
指定颜色
选择颜色表
颜色表标准化
自定义matplotlib
交互式绘图
交互式导航
在PythonShell中使用matplotlib
事件处理及拾取
所选示例
屏幕截图
我们最喜欢的秘籍
术语表
1

2

简介
原文:Introduction
译者:飞龙
协议:CCBY-NC-SA4.0
Matplotlib是一个用于在Python中绘制数组的2D图形库。虽然它起源于模仿
MATLAB®[1]图形命令,但它独立于MATLAB,可以以Pythonic和面向对象的方
式使用。虽然Matplotlib主要是在纯Python中编写的,但它大量使用NumPy和其
他扩展代码,即使对于大型数组也能提供良好的性能。
Matplotlib的设计理念是,你应该能够使用几个,或者只有一个命令创建简单的图
形。如果你想看到你的数据的直方图,你不需要实例化对象,调用方法,设置属性
等等;它应该能够工作。
多年来,我常常使用MATLAB进行数据分析和可视化。MATLAB擅长绘制漂亮的
图形。当我开始处理EEG数据时,我发现我需要编写应用程序来与我的数据交
互,并在MATLAB中开发了一个EEG分析应用程序。随着应用程序越来越复杂,
需要与数据库,http服务器交互,并操作复杂的数据结构,我开始与MATLAB作
为一种编程语言的限制而抗争,并决定迁移到Python。Python作为一种编程语
言,弥补了MATLAB的所有缺陷,但我很难找到一个2D绘图包(3DVTK则超过
了我的所有需求)。
当我去寻找一个Python绘图包时,我有几个要求:
绘图应该看起来不错-发布质量。对我来说一个重要的要求是文本看起来不错
(抗锯齿等)
用于包含TeX文档的Postscript输出
可嵌入图形用户界面用于应用程序开发
代码应该足够容易,我可以理解它,并扩展它
绘图应该很容易
没有找到适合我的包,我做了任何自称Python程序员会做的事情:撸起我的袖子
开始自己造。我没有任何真正的计算机图形经验,决定模仿MATLAB的绘图功
能,因为MATLAB做得很好。这有额外的优势,许多人有很多MATLAB的经验,
因此,他们可以很快开始在python中绘图。从开发人员的角度来看,拥有固定的
用户接口(pylab接口)非常有用,因为代码库的内容可以重新设计,而不会影响
用户代码。
Matplotlib代码在概念上分为三个部分:pylab接口是由 matplotlib.pylab提供
的函数集,允许用户使用非常类似于MATLAB图生成代码(Pyplot教程)的代码
创建绘图。Matplotlib前端或MatplotlibAPI是一组重要的类,创建和管理图形,
文本,线条,图表等(艺术家教程)。这是一个对输出无所了解的抽象接口。后端
是设备相关的绘图设备,也称为渲染器,将前端表示转换为打印件或显示设备(什
么是后端?)。后端示例:PS创建PostScript®打印件,SVG创建可缩放矢量图
简介
4

形打印件,Agg使用Matplotlib附带的高质量反颗粒几何库创建PNG输出,GTK
在Gtk+应用程序中嵌入Matplotlib,GTKAgg使用反颗粒渲染器创建图形并将其嵌
入到Gtk+应用程序中,以及用于PDF,WxWidgets,Tkinter等。
Matplotlib被很多人在许多不同的上下文中使用。有些人希望自动生成PostScript
文件以发送给打印机或发布商。其他人在Web应用程序服务器上部署Matplotlib
来生成PNG输出,并包含在动态生成的网页中。一些人在Windows™上的
Tkinter的Pythonshell中以交互方式使用Matplotlib。我的主要用途是将
Matplotlib嵌入Windows,Linux和MacintoshOSX上运行的Gtk+EEG应用程
序中。
[1]MATLAB是MathWorks公司的注册商标。
简介
5

安装
原文:Installing
译者:飞龙
协议:CCBY-NC-SA4.0
有许多安装matplotlib的不同方法,最好的方法取决于你使用的操作系统,已经安
装的内容以及如何使用它。为了避免涉及本页上的所有细节(和潜在的复杂性),
有几个方便的选项。
安装预构建包
多数平台:Python科学分发包
第一个选项是使用已经内置matplotlib的预打包的Python分发包。
Continuum.ioPython分发包(Anaconda或miniconda)和Enthought分发包
(Canopy)都是『在Windows,OSX和主流Linux平台开箱即用并正常工作』的
出色选择。这两个分发包包括matplotlib和许多其他有用的工具。
Linux:使用你的包管理器
如果你是用Linux,你可能更倾向于使用包管理器。matplotlib是用于多数主流
Linux发行版的包。
Debian/Ubuntu:sudoapt-getinstallpython-matplotlib
Fedora/Redhat:sudoyuminstallpython-matplotlib
MacOSX:使用 pip
如果你使用MacOS,你可以使用Python标准安装程序 pip来安装matplotlib二
进制。参见安装MacOS二进制轮子。
Windows
如果你还没有安装Python,我们建议使用兼容SciPy技术栈的Python分发版本,
如WinPython,Python(x,y),EnthoughtCanopy或ContinuumAnaconda,它们
含有matplotlib和它的许多依赖,并预装了其他有用的软件包。
对于Python的标准安装,可以使用 pip安装matplotlib:
python-mpipinstall-Upipsetuptools
python-mpipinstallmatplotlib
安装
6

如果没有为所有用户安装Python2.7或3.4,则需要安装MicrosoftVisualC++
2008(对于Python2.7为64位或32位)或MicrosoftVisualC++2010(对于
Python3.4为64位或32位)再分发包。
Matplotlib依赖于Pillow来读取和保存JPEG,BMP和TIFF图像文件。Matplotlib
需要MiKTeX和GhostScript来使用LaTeX渲染文本。动画模块需要FFmpeg,
avconv,mencoder或ImageMagick。
以下后端应该开箱即用:agg,tkagg,ps,pdf和svg。对于其他后端,你可能需
要安装pycairo,PyQt4,PyQt5,PySide,wxPython,PyGTK,Tornado或
GhostScript。
TkAgg可能是来自标准Pythonshell或IPython的,用于交互式的最佳后端。它被
启用为官方二进制文件的默认后端。Windows不支持GTK3。
PyPI下载页面上的Windows轮子( *.whl)不包含测试数据或示例代码。如果
你想尝试matplotlib源代码中的许多演示,请下载 *.tar.gz文件并查
看examples子目录。要运行测试套件,请将源代码发行版中
的lib\matplotlib\tests和lib\mpl_toolkits\tests目录分别复制
到sys.prefix\Lib\site-packages\matplotlib和sys.prefix\Lib\site-packages\mpl_toolkits
,并安装nose,mock,Pillow,MiKTeX,GhostScript,ffmpeg,avconv,
mencoder,ImageMagick和Inkscape。
从源码安装
如果你有兴趣为matplotlib开发做贡献,运行最新的源代码,或者只是想自己构建
一切,从源代码构建matplotlib并不困难。从PyPI文件页面抓取最新
的tar.gz发布文件,或者如果你想开发matplotlib或只需要最新的bug修复版
本,获取最新的git版本,请见从git安装。
源代码遵守标准环境变量CC,CXX,PKG_CONFIG。这意味着如果你的工具链
有前缀,你可以设置它们。这可以用于交叉编译。
exportCC=x86_64-pc-linux-gnu-gccexportCXX=x86_64-pc-linux-gnu
-g++exportPKG_CONFIG=x86_64-pc-linux-gnu-pkg-config
一旦你满足的了面的具体需求(主要是Python、NumPy、libpng和freetype),
你就可以构建matplotlib了:
cdmatplotlib
pythonsetup.pybuild
pythonsetup.pyinstall
我们提供与 setup.py一起使用的 setup.cfg文件,你可以使用它来自定义构建
过程。例如,要使用的默认后端,是否安装matplotlib附带的某些可选库,等等。
这个文件会对那些包装matplotlib的东西特别有用。
安装
7

如果已经为非标准设施安装了必备组件,并需要通知matplotlib它们在哪里,请编
辑setupext.py并将基本路径添加为 sys.platform的basedir字典条目。
例如,如果某些所需库的头文件位于 /some/path/include/someheader.h中,
请在你的平台的 basedir列表中输入 /some/path。
构建需求
这些是外部软件包,你需要在安装matplotlib之前安装它们。如果你在OSX上构
建,请参阅在OSX上构建。如果你在Windows上构建,请参阅在Windows上构
建。如果在Linux上使用软件包管理器安装依赖项,则除了库本身之外,还可能需
要安装开发包(查找 -dev后缀)。
所需依赖
Python2.7,3.4,3.5或3.6
下载Python
NumPy1.7.1(或更新)
Python的数组支持(下载NumPy)
setuptools
setuptools为Python包安装提供扩展
dateutil1.1或更新
为Python时间日期的处理提供扩展。如果使用了 pip,easy_install或者从
源码安装,安装器会尝试从PyPI下载并安装 python_dateutil。
pyparsing
需要为matplotlib的mathtext数学渲染提供支持。如果使用
了pip,easy_install或者从源码安装,安装器会尝试从PyPI下载并安
装pyparsing。
libpng1.2(或更新)
用于加载和保存PNG文件(下载)。libong需要zlib。
pytz
用于操作时区感知的日期时间。https://pypi.python.org/pypi/pytz
FreeType2.3或更新
用于读取TrueType字体文件。如果使用了 pip,easy_install或者从源码安
装,安装器会尝试从预期位置定位FreeType。如果找病毒奥,尝试安装pkg-
config,用于寻找所需非Python库的工具。
cycler0.10.1或更新
安装
8

可组合的循环类,用于构造style-cycle。
six
需要用于Python2和3之间的兼容性。
Python2的依赖
functools32
需要用于Python2.7上的兼容性。
subprocess32
可选,仅用于Unix。subprocess标准库从3.2+到2.7的Backport。它提供了更
好的错误信息和超时支持。
可选的GUI框架
这些是可选软件包,你可能希望安装这些软件包来使用matplotlib和用户界面工具
包。有关matplotlib可选后端和所提供功能的更多详细信息,请参阅什么是后端。
tk8.3或更新,不包括8.6.0和8.6.1
TkAgg后端使用的TCL/Tk窗口控件库。
版本8.6.0和8.6.1已知有问题,当以错误的顺序关闭多个窗口时可能导致段错
误。
pyqt4.4或更新
Qt4控件库的Python包装,用于Qt4Agg后端。
pygtk2.4或更新
GTK控件库的Python包装,用于GTK或者GTKAgg后端。
wxpython2.8或更新
wx控件库的Python包装,用于WX或WXAgg后端。
可选的外部程序
ffmpeg/avconv或mencoder
需要用于动画模块,将输出保存为电影格式。
ImageMagick
需要用于动画模块,能够保存GIF动画。
安装
9

可选依赖
Pillow
如果安装了Pillow,matplotlib可以读取或写入大部分图像文件格式。
pkg-config
用于寻找所需非Python库的工具。并不是严格需要它,但是如果库和头文件不在
预期位置,可以使安装更加便捷。
matplotlib自带的所需库
agg2.4
C++渲染引擎。matplotlib静态链接到agg模板源码,所以它除了matplotlib之
外,不会影响你的系统的任何东西。
qhull2012.1
用于计算Delaunay三角测量的库。
ttconv
TureType字体工具。
在Linux上构建
使用你的系统包管理器来安装依赖最为简单。
如果你使用Debian/Ubuntu,可以使用以下命令在获取需要用于构建matplotlib的
所有依赖:
sudoapt-getbuild-deppython-matplotlib
如果你使用Fedora/RedHat,你可以使用以下命令:
su-c"yum-builddeppython-matplotlib"
这不会构建matplotlib,但这会安装所需依赖。这会使从源码构建变得容易。
在OSX上构建
由于可以获取 libpng和freetype需求(darwinports,fink,/usr/X11R6)的不
同位置,不同的架构(例如x86,ppc,universal)和不同的OSX版本10.4和
10.5),OSX的构建情况很复杂。我们建议你使用我们对OSX版本所做的方式来
安装
10

教程
教程
12

pyplot教程
原文:Pyplottutorial
译者:飞龙
协议:CCBY-NC-SA4.0
matplotlib.pyplot是一个命令风格函数的集合,使 matplotlib的机制更像
MATLAB。每个绘图函数对图形进行一些更改:例如,创建图形,在图形中创建绘
图区域,在绘图区域绘制一些线条,使用标签装饰绘图等。
在matplotlib.pyplot中,各种状态跨函数调用保存,以便跟踪诸如当前图形和
绘图区域之类的东西,并且绘图函数始终指向当前轴域(请注意,这里和文档中的
大多数位置中的『轴域』(axes)是指图形的一部分(两条坐标轴围成的区域),
而不是指代多于一个轴的严格数学术语)。
importmatplotlib.pyplotasplt
plt.plot([1,2,3,4])
plt.ylabel('somenumbers')
plt.show()
Pyplot教程
13

你可能想知道为什么 x轴的范围为 0-3,y轴的范围为 1-4。如果你
向plot()命令提供单个列表或数组,则 matplotlib假定它是一个 y值序列,
并自动为你生成 x值。由于python范围从0开始,默认 x向量具有与 y相同
的长度,但从0开始。因此 x数据是 [0,1,2,3]。
plot()是一个通用命令,并且可接受任意数量的参数。例如,要绘
制x和y,你可以执行命令:
plt.plot([1,2,3,4],[1,4,9,16])
对于每个 x,y参数对,有一个可选的第三个参数,它是指示图形颜色和线条类型
的格式字符串。格式字符串的字母和符号来自MATLAB,并且将颜色字符串与线
型字符串连接在一起。默认格式字符串为 "b-",它是一条蓝色实线。例如,要
绘制上面的红色圆圈,你需要执行:
importmatplotlib.pyplotasplt
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.axis([0,6,0,20])
plt.show()
有关线型和格式字符串的完整列表,请参见 plot()文档。上例中的 axis()命
令接收 [xmin,xmax,ymin,ymax]的列表,并指定轴域的可视区域。
Pyplot教程
14

如果 matplotlib仅限于使用列表,它对于数字处理是相当无用的。一般来说,
你可以使用 numpy数组。事实上,所有序列都在内部转换为 numpy数组。下面
的示例展示了使用数组和不同格式字符串,在一条命令中绘制多个线条。
importnumpyasnp
importmatplotlib.pyplotasplt
#evenlysampledtimeat200msintervals
t=np.arange(0.,5.,0.2)
#reddashes,bluesquaresandgreentriangles
plt.plot(t,t,'r--',t,t**2,'bs',t,t**3,'g^')
plt.show()
控制线条属性
线条有许多你可以设置的属
性: linewidth,dashstyle,antialiased等,请参
见matplotlib.lines.Line2D。有几种方法可以设置线属性:
使用关键字参数:
plt.plot(x,y,linewidth=2.0)
Pyplot教程
15

使用 Line2D实例的 setter方法。plot返回 Line2D对象的列表,例
如line1,line2=plot(x1,y1,x2,y2)。在下面的代码中,我们假设只
有一行,返回的列表长度为1。我们对 line使用元组解构,得到该列表的第
一个元素:
line,=plt.plot(x,y,'-')
line.set_antialiased(False)#turnoffantialising
使用 setp()命令。下面的示例使用MATLAB风格的命令来设置线条列表上
的多个属性。setp使用对象列表或单个对象透明地工作。你可以使用
python关键字参数或MATLAB风格的字符串/值对:
lines=plt.plot(x1,y1,x2,y2)
#使用关键字参数
plt.setp(lines,color='r',linewidth=2.0)
#或者MATLAB风格的字符串值对
plt.setp(lines,'color','r','linewidth',2.0)
下面是可用的 Line2D属性。
属性 值类型
alpha 浮点值
animated [True/False]
antialiasedoraa [True/False]
clip_box matplotlib.transform.Bbox实例
clip_on [True/False]
clip_path Path实例,Transform,以及 Patch实例
colororc 任何matplotlib颜色
contains 命中测试函数
dash_capstyle ['butt'/'round'/'projecting']
dash_joinstyle ['miter'/'round'/'bevel']
dashes 以点为单位的连接/断开墨水序列
data (np.arrayxdata,np.arrayydata)
figure matplotlib.figure.Figure实例
label 任何字符串
linestyleor ls ['-'/'--'/'-.'/':'/'steps'/...]
Pyplot教程
16

linewidthor lw 以点为单位的浮点值
lod [True/False]
marker ['+'/','/'.'/'1'/'2'/'3'/'4']
markeredgecolorormec 任何matplotlib颜色
markeredgewidthormew 以点为单位的浮点值
markerfacecolorormfc 任何matplotlib颜色
markersizeorms 浮点值
markevery [None/整数值/(startind,stride)]
picker 用于交互式线条选择
pickradius 线条的拾取选择半径
solid_capstyle ['butt'/'round'/'projecting']
solid_joinstyle ['miter'/'round'/'bevel']
transform matplotlib.transforms.Transform实例
visible [True/False]
xdata np.array
ydata np.array
zorder 任何数值
要获取可设置的线条属性的列表,请以一个或多个线条作为参数调用 step()函数
In[69]:lines=plt.plot([1,2,3])
In[70]:plt.setp(lines)
alpha:float
animated:[True|False]
antialiasedoraa:[True|False]
...snip
处理多个图形和轴域
MATLAB和pyplot具有当前图形和当前轴域的概念。所有绘图命令适用于当前轴
域。函数 gca()返回当前轴域(一个 matplotlib.axes.Axes实
例), gcf()返回当前图形( matplotlib.figure.Figure实例)。通常,你
不必担心这一点,因为它都是在幕后处理。下面是一个创建两个子图的脚本。
Pyplot教程
17

importnumpyasnp
importmatplotlib.pyplotasplt
deff(t):
returnnp.exp(-t)*np.cos(2*np.pi*t)
t1=np.arange(0.0,5.0,0.1)
t2=np.arange(0.0,5.0,0.02)
plt.figure(1)
plt.subplot(211)
plt.plot(t1,f(t1),'bo',t2,f(t2),'k')
plt.subplot(212)
plt.plot(t2,np.cos(2*np.pi*t2),'r--')
plt.show()
这里的 figure()命令是可选的,因为默认情况下将创建 figure(1),如果不手
动指定任何轴域,则默认创建 subplot(111)。subplot()命令指
定numrows,numcols,fignum,其中 fignum的范围是
从1到numrows*numcols。如果 numrows*numcols<10,
则subplot命令中的逗号是可选的。因此,子
图subplot(211)与subplot(2,1,1)相同。你可以创建任意数量的子图和轴
域。如果要手动放置轴域,即不在矩形网格上,请使用 axes()命令,该命令允
许你将 axes([left,bottom,width,height])指定为位置,其中所有值都使
Pyplot教程
18

用小数(0到1)坐标。手动放置轴域的示例请参见 pylab_examples示例代
码: axes_demo.py,具有大量子图的示例请参见 pylab_examples示例代
码: subplots_demo.py。
你可以通过使用递增图形编号多次调用 figure()来创建多个图形。当然,每个
数字可以包含所需的轴和子图数量:
importmatplotlib.pyplotasplt
plt.figure(1)#第一个图形
plt.subplot(211)#第一个图形的第一个子图
plt.plot([1,2,3])
plt.subplot(212)#第一个图形的第二个子图
plt.plot([4,5,6])
plt.figure(2)#第二个图形
plt.plot([4,5,6])#默认创建subplot(111)
plt.figure(1)#当前是图形1,subplot(212)
plt.subplot(211)#将第一个图形的subplot(211)设为当前
子图
plt.title('Easyas1,2,3')#子图211的标题
你可以使用 clf()清除当前图形,使用 cla()清除当前轴域。如果你搞不清在
幕后维护的状态(特别是当前的图形和轴域),不要绝望:这只是一个面向对象的
API的简单的状态包装器,你可以使用面向对象API(见艺术家教程)。
如果你正在制作大量的图形,你需要注意一件事:在一个图形用 close()显式关
闭之前,该图所需的内存不会完全释放。删除对图形的所有引用,和/或使用窗口
管理器杀死屏幕上出现的图形的窗口是不够的,因为在调用 close()之
前, pyplot会维护内部引用。
处理文本
text()命令可用于在任意位置添加文
本, xlabel(),ylabel()和title()用于在指定的位置添加文本(详细示
例请参阅文本介绍)。
Pyplot教程
19

importnumpyasnp
importmatplotlib.pyplotasplt
mu,sigma=100,15
x=mu+sigma*np.random.randn(10000)
#数据的直方图
n,bins,patches=plt.hist(x,50,normed=1,facecolor='g',alph
a=0.75)
plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('HistogramofIQ')
plt.text(60,.025,r'$\mu=100,\\sigma=15$')
plt.axis([40,160,0,0.03])
plt.grid(True)
plt.show()
所有的 text()命令返回一个 matplotlib.text.Text实例。与上面一样,你可
以通过将关键字参数传递到 text函数或使用 setp()来自定义属性:
t=plt.xlabel('mydata',fontsize=14,color='red')
这些属性的更详细介绍请见文本属性和布局。
Pyplot教程
20

在文本中使用数学表达式
matplotlib在任何文本表达式中接受TeX方程表达式。例如,要在标题中写入
表达式,可以编写一个由美元符号包围的TeX表达式:
plt.title(r'$\sigma_i=15$')
标题字符串之前的 r很重要-它表示该字符串是一个原始字符串,而不是将反斜
杠作为python转义处理。matplotlib有一个内置的TeX表达式解析器和布局
引擎,并且自带了自己的数学字体-详细信息请参阅编写数学表达式。因此,你可
以跨平台使用数学文本,而无需安装TeX。对于安装了LaTeX和dvipng的用
户,还可以使用LaTeX格式化文本,并将输出直接合并到显示图形或保存的
postscript中-请参阅使用LaTeX进行文本渲染。
标注文本
上面的 text()基本命令将文本放置在轴域的任意位置。文本的一个常见用法是
对图的某些特征执行标注,而 annotate()方法提供一些辅助功能,使标注变得
容易。在标注中,有两个要考虑的点:由参数 xy表示的标注位置和 xytext表
示的文本位置。这两个参数都是 (x,y)元组。
Pyplot教程
21

importnumpyasnp
importmatplotlib.pyplotasplt
#生成一些区间[0,1]内的数据
y=np.random.normal(loc=0.5,scale=0.4,size=1000)
y=y[(y>0)&(y<1)]
y.sort()
x=np.arange(len(y))
#带有多个轴域刻度的plot
plt.figure(1)
#线性
plt.subplot(221)
plt.plot(x,y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)
#对数
plt.subplot(222)
plt.plot(x,y)
plt.yscale('log')
plt.title('log')
plt.grid(True)
#对称的对数
plt.subplot(223)
plt.plot(x,y-y.mean())
plt.yscale('symlog',linthreshy=0.05)
plt.title('symlog')
plt.grid(True)
#logit
plt.subplot(224)
plt.plot(x,y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
plt.show()
Pyplot教程
23

图像教程
原文:Imagetutorial
译者:飞龙
协议:CCBY-NC-SA4.0
启动命令
首先,让我们启动IPython。它是Python标准提示符的最好的改进,它与
Matplotlib配合得相当不错。在shell或IPythonNotebook上都可以启动
IPython。
随着IPython启动,我们现在需要连接到GUI事件循环。它告诉IPython在哪里
(以及如何显示)绘图。要连接到GUI循环,请在IPython提示符处执
行%matplotlib魔法。在IPython的GUI事件循环文档中有更多的细节。
如果使用IPythonNotebook,可以使用相同的命令,但人们通常以特定参数使
用%matplotlib:
In[1]:%matplotlibinline
这将打开内联绘图,绘图图形将显示在笔记本中。这对交互性有很重要的影响。
对于内联绘图,在单元格下方的单元格中输出绘图的命令不会影响绘图。例如,从
创建绘图的单元格下面的单元格更改颜色表是不可能的。但是,对于其他后端,例
如qt4,它们会打开一个单独的窗口,那些创建绘图的单元格下方的单元格将改变
绘图-它是一个内存中的活对象。
本教程将使用 matplotlib的命令式绘图接口 pyplot。该接口维护全局状态,
并且可用于简单快速地尝试各种绘图设置。另一种是面向对象的接口,这也非常强
大,一般更适合大型应用程序的开发。如果你想了解面向对象接口,使用上的常见
问题是一个用于起步的不错的页面。现在,让我们继续使用命令式方式:
In[2]:importmatplotlib.pyplotasplt
In[3]:importmatplotlib.imageasmpimg
In[4]:importnumpyasnp
将图像数据导入到NumPy数组
加载图像数据由Pillow库提供支持。本来, matplotlib只支持PNG图像。如
果本机读取失败,下面显示的命令会回退到Pillow。
图像教程
25

此示例中使用的图像是PNG文件,但是请记住你自己的数据的Pillow要求。
下面是我们要摆弄的图片:
它是一个24位RGBPNG图像(每个R,G,B为8位)。根据你获取数据的位
置,你最有可能遇到的其他类型的图像是RGBA图像,拥有透明度或单通道灰度
(亮度)的图像。你可以右键单击它,选择 Saveimageas(另存为)为本教程
的剩余部分下载到你的计算机。
现在我们开始...
In[5]:img=mpimg.imread('stinkbug.png')
Out[5]:
array([[[0.40784314,0.40784314,0.40784314],
[0.40784314,0.40784314,0.40784314],
[0.40784314,0.40784314,0.40784314],
...,
[0.42745098,0.42745098,0.42745098],
[0.42745098,0.42745098,0.42745098],
[0.42745098,0.42745098,0.42745098]],
...,
[[0.44313726,0.44313726,0.44313726],
[0.4509804,0.4509804,0.4509804],
[0.4509804,0.4509804,0.4509804],
...,
[0.44705883,0.44705883,0.44705883],
[0.44705883,0.44705883,0.44705883],
[0.44313726,0.44313726,0.44313726]]],dtype=float32
)
图像教程
26

注意这里的 dtype- float32。Matplotlib已将每个通道的8位数据重新定标为
0.0和1.0之间的浮点数。作为旁注,Pillow可以使用的唯一数据类型
是uint8。Matplotlib绘图可以处理 float32和uint8,但是对于除PNG之
外的任何格式的图像,读取/写入仅限于 uint8数据。为什么是8位呢?大多数
显示器只能渲染每通道8位的颜色渐变。为什么他们只能渲染每通道8位呢?因
为这会使所有人的眼睛可以看到。更多信息请见(从摄影的角度):Luminous
Landscape位深度教程。
每个内部列表表示一个像素。这里,对于RGB图像,有3个值。由于它是一个黑
白图像,R,G和B都是类似的。RGBA(其中A是阿尔法或透明度)对于每个内
部列表具有4个值,而且简单亮度图像仅具有一个值(因此仅是二维数组,而不是
三维数组)。对于RGB和RGBA图像, matplotlib支
持float32和uint8数据类型。对于灰度, matplotlib只支持 float32。
如果你的数组数据不符合这些描述之一,则需要重新缩放它。
将NumPy数组绘制为图像
所以,你将数据保存在一个 numpy数组(通过导入它,或生成它)。让我们渲染
它吧。在Matplotlib中,这是使用 imshow()函数执行的。这里我们将抓
取plot对象。这个对象提供了一个简单的方法来从提示符处理绘图。
In[6]:imgplot=plt.imshow(img)
你也可以绘制任何NumPy数组。
图像教程
27

对图像绘图应用伪彩色方案
伪彩色可以是一个有用的工具,用于增强对比度和更易于可视化你的数据。这在使
用投影仪对你的数据进行演示时尤其有用-它们的对比度通常很差。
伪彩色仅与单通道,灰度,亮度图像相关。我们目前有一个RGB图像。由于R,G
和B都是相似的(见上面或你的数据),我们可以只选择一个通道的数据:
In[7]:lum_img=img[:,:,0]
这是数组切片,更多信息请见NumPy教程。
In[8]:plt.imshow(lum_img)
现在,亮度(2D,无颜色)图像应用了默认颜色表(也称为查找表,LUT)。默
认值称为 jet。有很多其他方案可以选择。
In[9]:plt.imshow(lum_img,cmap="hot")
图像教程
28

请注意,你还可以使用 set_cmap()方法更改现有绘图对象上的颜色:
In[10]:imgplot=plt.imshow(lum_img)
In[11]:imgplot.set_cmap('spectral')
图像教程
29

这会为你现有的图形添加一个颜色条。如果你更改并切换到不同的颜色映射,则不
会自动更改-你必须重新创建绘图,并再次添加颜色条。
检查特定数据范围
有时,你想要增强图像的对比度,或者扩大特定区域的对比度,同时牺牲变化不
大,或者无所谓的颜色细节。找到有趣区域的最好工具是直方图。要创建我们的
图像数据的直方图,我们使用 hist()函数。
In[14]:plt.hist(lum_img.ravel(),bins=256,range=(0.0,1.0),f
c='k',ec='k')
图像教程
31

通常,图像的『有趣』部分在峰值附近,你可以通过剪切峰值上方和/或下方的区域
获得额外的对比度。在我们的直方图中,看起来最大值处没有太多有用的信息(图
像中有很多不是白色的东西)。让我们调整上限,以便我们有效地『放大』直方图
的一部分。我们通过将 clim参数传递给 imshow来实现。你也可以通过对图像
绘图对象调用 set_clim()方法来做到这一点,但要确保你在使用IPython
Notebook的时候,和 plot命令在相同的单元格中执行-它不会改变之前单元格
的图。
In[15]:imgplot=plt.imshow(lum_img,clim=(0.0,0.7))
图像教程
32

数组插值方案
插值根据不同的数学方案计算像素『应有』的颜色或值。发生这种情况的一个常见
的场景是调整图像的大小。像素的数量会发生变化,但你想要相同的信息。由于
像素是离散的,因此存在缺失的空间。插值就是填补这个空间的方式。这就是当
你放大图像时,你的图像有时会出来看起来像素化的原因。当原始图像和扩展图像
之间的差异较大时,效果更加明显。让我们加载我们的图像并缩小它。我们实际
上正在丢弃像素,只保留少数几个像素。现在,当我们绘制它时,数据被放大为你
屏幕的大小。由于旧的像素不再存在,计算机必须绘制像素来填充那个空间。
我们将使用用来加载图像的Pillow库来调整图像大小。
In[16]:fromPILimportImage
In[17]:img=Image.open('../_static/stinkbug.png')
In[18]:img.thumbnail((64,64),Image.ANTIALIAS)#resizesimag
ein-place
In[19]:imgplot=plt.imshow(img)
图像教程
33

这里我们使用默认插值,双线性,因为我们没有向 imshow()提供任何插值参数。
让我们试试一些其它的东西:
最邻近
In[20]:imgplot=plt.imshow(img,interpolation="nearest")
图像教程
34

双立方
In[21]:imgplot=plt.imshow(img,interpolation="bicubic")
图像教程
35

双立方插值通常用于放大照片-人们倾向于模糊而不是过度像素化。
图像教程
36

使用GridSpec自定义子图位置
原文:CustomizingLocationofSubplotUsingGridSpec
译者:飞龙
协议:CCBY-NC-SA4.0
GridSpec
指定子图将放置的网格的几何位置。需要设置网格的行数和列数。子图布局参数
(例如,左,右等)可以选择性调整。
SubplotSpec
指定在给定 GridSpec中的子图位置。
subplot2grid
一个辅助函数,类似于 pyplot.subplot,但是使用基于0的索引,并可使子图
跨越多个格子。
subplot2grid基本示例
要使用subplot2grid,你需要提供网格的几何形状和网格中子图的位置。对于简单
的单网格子图:
ax=plt.subplot2grid((2,2),(0,0))
等价于:
ax=plt.subplot(2,2,1)
nRow=2,nCol=2
(0,0)+-------+-------+
|1||
+-------+-------+
|||
+-------+-------+
要注意不想 subplot,gridspec中的下标从0开始。
为了创建跨越多个格子的子图,
使用GridSpec自定义子图位置
37

ax2=plt.subplot2grid((3,3),(1,0),colspan=2)
ax3=plt.subplot2grid((3,3),(1,2),rowspan=2)
例如,下列命令:
ax1=plt.subplot2grid((3,3),(0,0),colspan=3)
ax2=plt.subplot2grid((3,3),(1,0),colspan=2)
ax3=plt.subplot2grid((3,3),(1,2),rowspan=2)
ax4=plt.subplot2grid((3,3),(2,0))
ax5=plt.subplot2grid((3,3),(2,1))
会创建:
GridSpec和SubplotSpec
你可以显式创建 GridSpec并用它们创建子图。
例如,
ax=plt.subplot2grid((2,2),(0,0))
等价于:
使用GridSpec自定义子图位置
38

importmatplotlib.gridspecasgridspec
gs=gridspec.GridSpec(2,2)
ax=plt.subplot(gs[0,0])
gridspec示例提供类似数组(一维或二维)的索引,并返回 SubplotSpec实
例。例如,使用切片来返回跨越多个格子的 SubplotSpec实例。
上面的例子会变成:
gs=gridspec.GridSpec(3,3)
ax1=plt.subplot(gs[0,:])
ax2=plt.subplot(gs[1,:-1])
ax3=plt.subplot(gs[1:,-1])
ax4=plt.subplot(gs[-1,0])
ax5=plt.subplot(gs[-1,-2])
调整GridSpec布局
在显式使用 GridSpec的时候,你可以调整子图的布局参数,子图
由gridspec创建。
使用GridSpec自定义子图位置
39

gs1=gridspec.GridSpec(3,3)
gs1.update(left=0.05,right=0.48,wspace=0.05)
这类似于 subplots_adjust,但是他只影响从给定 GridSpec创建的子图。
下面的代码
gs1=gridspec.GridSpec(3,3)
gs1.update(left=0.05,right=0.48,wspace=0.05)
ax1=plt.subplot(gs1[:-1,:])
ax2=plt.subplot(gs1[-1,:-1])
ax3=plt.subplot(gs1[-1,-1])
gs2=gridspec.GridSpec(3,3)
gs2.update(left=0.55,right=0.98,hspace=0.05)
ax4=plt.subplot(gs2[:,:-1])
ax5=plt.subplot(gs2[:-1,-1])
ax6=plt.subplot(gs2[-1,-1])
会产生
使用SubplotSpec创建GridSpec
使用GridSpec自定义子图位置
40

你可以从 SubplotSpec创建 GridSpec,其中它的布局参数设置为给
定SubplotSpec的位置的布局参数。
gs0=gridspec.GridSpec(1,2)
gs00=gridspec.GridSpecFromSubplotSpec(3,3,subplot_spec=gs0[0
])
gs01=gridspec.GridSpecFromSubplotSpec(3,3,subplot_spec=gs0[1
])
使用 SubplotSpec创建复杂嵌套的 GridSpec
这里有一个更复杂的嵌套 gridspec的示例,我们通过在每个3x3内部网格中隐
藏适当的脊线,在4x4外部网格的每个单元格周围放置一个框。
使用GridSpec自定义子图位置
41

网格尺寸可变的 GridSpec
通常, GridSpec创建大小相等的网格。你可以调整行和列的相对高度和宽度,要
注意绝对高度值是无意义的,有意义的只是它们的相对比值。
gs=gridspec.GridSpec(2,2,
width_ratios=[1,2],
height_ratios=[4,1]
)
ax1=plt.subplot(gs[0])
ax2=plt.subplot(gs[1])
ax3=plt.subplot(gs[2])
ax4=plt.subplot(gs[3])
使用GridSpec自定义子图位置
42

使用GridSpec自定义子图位置
43

密致布局指南
原文:TightLayoutguide
译者:飞龙
协议:CCBY-NC-SA4.0
tight_layout会自动调整子图参数,使之填充整个图像区域。这是个实验特
性,可能在一些情况下不工作。它仅仅检查坐标轴标签、刻度标签以及标题的部
分。
简单的示例
在matplotlib中,轴域(包括子图)的位置以标准化图形坐标指定。可能发生的
是,你的轴标签或标题(有时甚至是刻度标签)会超出图形区域,因此被截断。
plt.rcParams['savefig.facecolor']="0.8"
defexample_plot(ax,fontsize=12):
ax.plot([1,2])
ax.locator_params(nbins=3)
ax.set_xlabel('x-label',fontsize=fontsize)
ax.set_ylabel('y-label',fontsize=fontsize)
ax.set_title('Title',fontsize=fontsize)
plt.close('all')
fig,ax=plt.subplots()
example_plot(ax,fontsize=24)
密致布局教程
44

当你拥有多个子图时,你会经常看到不同轴域的标签叠在一起。
plt.close('all')
fig,((ax1,ax2),(ax3,ax4))=plt.subplots(nrows=2,ncols=2)
example_plot(ax1)
example_plot(ax2)
example_plot(ax3)
example_plot(ax4)
密致布局教程
46

tight_layout()也会调整子图之间的间隔来减少堆叠。
tight_layout()可以接受关键字参数 pad、w_pad或者 h_pad,这些参数
图像边界和子图之间的额外边距。边距以字体大小单位规定。
密致布局教程
47

plt.tight_layout(pad=0.4,w_pad=0.5,h_pad=1.0)
即使子图大小不同, tight_layout()也能够工作,只要网格的规定的兼容的。
在下面的例子中, ax1和ax2是2x2网格的子图,但是 ax3是1x2网格。
plt.close('all')
fig=plt.figure()
ax1=plt.subplot(221)
ax2=plt.subplot(223)
ax3=plt.subplot(122)
example_plot(ax1)
example_plot(ax2)
example_plot(ax3)
plt.tight_layout()
密致布局教程
48

它适用于使用 subplot2grid()创建的子图。一般来说,从 gridspec(使
用GridSpec自定义子布局的位置)创建的子图也能正常工作。
plt.close('all')
fig=plt.figure()
ax1=plt.subplot2grid((3,3),(0,0))
ax2=plt.subplot2grid((3,3),(0,1),colspan=2)
ax3=plt.subplot2grid((3,3),(1,0),colspan=2,rowspan=2)
ax4=plt.subplot2grid((3,3),(1,2),rowspan=2)
example_plot(ax1)
example_plot(ax2)
example_plot(ax3)
example_plot(ax4)
plt.tight_layout()
密致布局教程
49

虽然没有彻底测试,它看起来也适用于 aspect不为 auto的子图(例如带有图
像的轴域)。
arr=np.arange(100).reshape((10,10))
plt.close('all')
fig=plt.figure(figsize=(5,4))
ax=plt.subplot(111)
im=ax.imshow(arr,interpolation="none")
plt.tight_layout()
密致布局教程
50

警告
tight_layout()只考虑刻度标签,轴标签和标题。因此,其他艺术家可能
被截断并且也可能重叠。
它假定刻度标签,轴标签和标题所需的额外空间与轴域的原始位置无关。这通
常是真的,但在罕见的情况下不是。
pad=0将某些文本剪切几个像素。这可能是当前算法的错误或限制,并且
不清楚为什么会发生。同时,推荐使用至少大于0.3的间隔。
和GridSpec一起使用
GridSpec拥有自己的 tight_layout()方法(pyplotAPI
的tight_layout()也能生效)。
密致布局教程
51

plt.close('all')
fig=plt.figure()
importmatplotlib.gridspecasgridspec
gs1=gridspec.GridSpec(2,1)
ax1=fig.add_subplot(gs1[0])
ax2=fig.add_subplot(gs1[1])
example_plot(ax1)
example_plot(ax2)
gs1.tight_layout(fig)
你可以提供一个可选的 rect参数,指定子图所填充的边框。坐标必须为标准化
图形坐标,默认值为 (0,0,1,1)。
gs1.tight_layout(fig,rect=[0,0,0.5,1])
密致布局教程
52

例如,这可用于带有多个 gridspecs的图形。
gs2=gridspec.GridSpec(3,1)
forssings2:
ax=fig.add_subplot(ss)
example_plot(ax)
ax.set_title("")
ax.set_xlabel("")
ax.set_xlabel("x-label",fontsize=12)
gs2.tight_layout(fig,rect=[0.5,0,1,1],h_pad=0.5)
密致布局教程
53

我们可以尝试匹配两个网格的顶部和底部。
top=min(gs1.top,gs2.top)
bottom=max(gs1.bottom,gs2.bottom)
gs1.update(top=top,bottom=bottom)
gs2.update(top=top,bottom=bottom)
虽然这应该足够好了,调整顶部和底部可能也需要调整 hspace。为了更
新hspace和vspace,我们再次使用更新后的 rect参数调
用tight_layout()。注意, rect参数指定的区域包括刻度标签。因此,我们
将底部(正常情况下为0)增加每个 gridspec的底部之差。顶部也一样。
top=min(gs1.top,gs2.top)
bottom=max(gs1.bottom,gs2.bottom)
gs1.tight_layout(fig,rect=[None,0+(bottom-gs1.bottom),
0.5,1-(gs1.top-top)])
gs2.tight_layout(fig,rect=[0.5,0+(bottom-gs2.bottom),
None,1-(gs2.top-top)],
h_pad=0.5)
密致布局教程
54

和AxesGrid1一起使用
虽然受限但也支持 axes_grid1工具包
plt.close('all')
fig=plt.figure()
frommpl_toolkits.axes_grid1importGrid
grid=Grid(fig,rect=111,nrows_ncols=(2,2),
axes_pad=0.25,label_mode='L',
)
foraxingrid:
example_plot(ax)
ax.title.set_visible(False)
plt.tight_layout()
密致布局教程
55

颜色条
如果你使用 colorbar命令创建了颜色条,创建的颜色条是 Axes而不
是Subplot的实例,所以 tight_layout没有效果。在Matplotlibv1.1中,你可
以使用 gridspec将颜色条创建为子图。
plt.close('all')
arr=np.arange(100).reshape((10,10))
fig=plt.figure(figsize=(4,4))
im=plt.imshow(arr,interpolation="none")
plt.colorbar(im,use_gridspec=True)
plt.tight_layout()
![])http://matplotlib.org/_images/tight_layout_guide-14.png
另一个选项是使用 AxesGrid1工具包,显式为颜色条创建一个轴域:
密致布局教程
56

plt.close('all')
arr=np.arange(100).reshape((10,10))
fig=plt.figure(figsize=(4,4))
im=plt.imshow(arr,interpolation="none")
frommpl_toolkits.axes_grid1importmake_axes_locatable
divider=make_axes_locatable(plt.gca())
cax=divider.append_axes("right","5%",pad="3%")
plt.colorbar(im,cax=cax)
plt.tight_layout()
密致布局教程
57

艺术家教程
原文:Artisttutorial
译者:飞龙
协议:CCBY-NC-SA4.0
matplotlibAPI有三个层级。matplotlib.backend_bases.FigureCanvas是绘
制图形的区域, matplotlib.backend_bases.Renderer是知道如何
在ChartCanvas上绘制的对象,而 matplotlib.artist.Artist是知道如何使
用渲染器在画布上画图的对象。FigureCanvas和Renderer处理与用户界面工
具包(如wxPython)或PostScript®等绘图语言交互的所有细节, Artist处理
所有高级结构,如表示和布局图形,文本和线条。用户通常要花费95%的时间来处
理艺术家。
有两种类型的艺术家:基本类型和容器类型。基本类型表示我们想要绘制到画布上
的标准图形对象: Line2D,Rectangle,Text,AxesImage等,容器是放
置它们的位置( Axis,Axes和Figure)。标准用法是创建一个 Figure实
例,使用 Figure创建一个或多个 Axes或Subplot实例,并使用 Axes实例
的辅助方法来创建基本类型。在下面的示例中,我们使
用matplotlib.pyplot.figure()创建一个 Figure实例,这是一个便捷的方
法,用于实例化 Figure实例并将它们与你的用户界面或绘图工具
包FigureCanvas连接。正如我们将在下面讨论的,这不是必须的-你可以直接使
用PostScript,PDF,Gtk+或wxPython FigureCanvas实例,直接实例化你的
图形并连接它们-但是因为我们在这里关注艺术家API,我们让 pyplot为我们处
理一些细节:
importmatplotlib.pyplotasplt
fig=plt.figure()
ax=fig.add_subplot(2,1,1)#tworows,onecolumn,firstplot
Axes可能是matplotlibAPI中最重要的类,你将在大多数时间使用它。这是因
为Axes是大多数对象所进入的绘图区域, Axes有许多特殊的辅助方法
(plot(),text(),hist(),imshow())来创建最常见的图形基本类型
Line2D,Text,Rectangle,Image)。这些辅助方法将获取你的数据
(例如numpy数组和字符串),并根据需要创建基本 Artist实例(例
如, Line2D),将它们添加到相关容器中,并在请求时绘制它们。大多数人可
能熟悉子图,这只是 Axes的一个特例,它存在于 Subplot实例的列网格的固定
行上。如果要在任意位置创建 Axes,只需使用 add_axes()方法,该方法接
受[left,bottom,width,height]值的列表,以0~1的图形相对坐标为单
位:
艺术家教程
58

fig2=plt.figure()
ax2=fig2.add_axes([0.15,0.1,0.7,0.3])
以我们的例子继续:
importnumpyasnp
t=np.arange(0.0,1.0,0.01)
s=np.sin(2*np.pi*t)
line,=ax.plot(t,s,color='blue',lw=2)
在这个例子中, ax是上面的 fig.add_subplot调用创建的 Axes实例(记
住Subplot只是 Axes的一个子类),当你调用 ax.plot时,它创建一
个Line2D实例并将其添加到 Axes.lines列表中。在下面的ipython交互式会
话中,你可以看到 Axes.lines列表的长度为1,并且包含
由line,=ax.plot...调用返回的相同线条:
In[101]:ax.lines[0]
Out[101]:<matplotlib.lines.Line2Dinstanceat0x19a95710>
In[102]:line
Out[102]:<matplotlib.lines.Line2Dinstanceat0x19a95710>
如果你对 ax.plot进行连续调用(并且保持状态为『on』,这是默认值),则将
在列表中添加其他线条。你可以稍后通过调用列表方法删除线条;任何一个方法都
可以:
delax.lines[0]
ax.lines.remove(line)#oneortheother,notboth!
轴域也拥有辅助方法,用于设置和装饰x和y轴的刻度、刻度标签和轴标签:
xtext=ax.set_xlabel('myxdata')#returnsaTextinstance
ytext=ax.set_ylabel('myydata')
当你调用 ax.set_xlabel时,它将信息传递给 XAxis的Text实例,每
个Axes实例都包含 XAxis和YAxis,它们处理刻度、刻度标签和轴标签的布
局和绘制。
尝试创建下面的图形:
艺术家教程
59

自定义你的对象
图中的每个元素都由一个matplotlib艺术家表示,每个元素都有一个扩展属性列表
用于配置它的外观。图形本身包含一个 Rectangle,正好是图形的大小,你可以
使用它来设置图形的背景颜色和透明度。同样,每个 Axes边框(在通常的
matplotlib绘图中是标准的白底黑边)拥有一个 Rectangle实例,用于确定轴域
的颜色,透明度和其他属性,这些实例存储为成员变
量Figure.patch和Axes.patch(『Patch』是一个继承自MATLAB的名称,
它是图形上的一个颜色的2D『补丁』,例如矩形,圆和多边形)。每个matplotlib
艺术家都有以下属性。
艺术家教程
60

属性 描述
alpha 透明度-0~1的标量
animated 用于帮助动画绘制的布尔值
axes 艺术家所在的轴域,可能为空
clip_box 用于剪切艺术家的边框
clip_on 剪切是否开启
clip_path 艺术家被剪切的路径
contains 一个拾取函数,用于判断艺术家是否位于拾取点
figure 艺术家所在的图形实例,可能为空
label 文本标签(用于自动标记)
picker 控制对象拾取的Python对象
transform 变换
visible 布尔值,表示艺术家是否应该绘制
zorder 确定绘制顺序的数值
rasterized 布尔值,是否将向量转换为光栅图形(出于压缩或eps透明度)
每个属性都使用一个老式的 setter或getter(是的,我们知道这会刺激
Python爱好者,我们计划支持通过属性或traits直接访问,但它还没有完成)。例
如,要将当前 alpha值变为一半:
a=o.get_alpha()
o.set_alpha(0.5*a)
如果你打算可以一次性设置一些属性,你也可以以关键字参数使用 set方法,例
如:
o.set(alpha=0.5,zorder=2)
如果你在Python交互式Shell中工作,检查 Artist属性的一种方便的方法是使
用matplotlib.artist.getp()函数(在pylab中只需要 getp()),它列出了
属性及其值。这适用于从 Artist派生的类,例如 Figure和Rectangle。这
里是上面提到的 Figure的矩形属性:
艺术家教程
61

In[149]:matplotlib.artist.getp(fig.patch)
alpha=1.0
animated=False
antialiasedoraa=True
axes=None
clip_box=None
clip_on=False
clip_path=None
contains=None
edgecolororec=w
facecolororfc=0.75
figure=Figure(8.125x6.125)
fill=1
hatch=None
height=1
label=
linewidthorlw=1.0
picker=None
transform=<Affineobjectat0x134cca84>
verts=((0,0),(0,1),(1,1),(1,0))
visible=True
width=1
window_extent=<Bboxobjectat0x134acbcc>
x=0
y=0
zorder=1
所有类的文档字符串也包含 Artist属性,因此你可以查阅交互式『帮助』或
Artist模块,来获取给定对象的属性列表。
对象容器
现在我们知道如何检查和设置我们想要配置的给定对象的属性,现在我们需要如何
获取该对象。前面提到了两种对象:基本类型和容器类型。基本类型通常是你想
要配置的东西( Text实例的字体, Line2D的宽度),虽然容器也有一些属性-
例如Axes是一个容器艺术家,包含你的绘图中的许多基本类型,但它也有属
性,比如 xscale来控制 xaxis是『线性』还是『对数』。在本节中,我们将回
顾各种容器对象存储你想要访问的艺术家的位置。
图形容器
顶层容器艺术家是 matplotlib.figure.Figure,它包含图形中的所有内容。图
形的背景是一个 Rectangle,存储在 Figure.patch中。当你向图形中添加子
图( add_subplot())和轴域( add_axes())时,这些会附加
到Figure.axes。它们也由创建它们的方法返回:
艺术家教程
62

In[156]:fig=plt.figure()
In[157]:ax1=fig.add_subplot(211)
In[158]:ax2=fig.add_axes([0.1,0.1,0.7,0.3])
In[159]:ax1
Out[159]:<matplotlib.axes.Subplotinstanceat0xd54b26c>
In[160]:printfig.axes
[<matplotlib.axes.Subplotinstanceat0xd54b26c>,<matplotlib.ax
es.Axesinstanceat0xd3f0b2c>]
因为图形维护了『当前轴域』(见 figure.gca和图 figure.sca)的概念以支
持pylab/pyplot状态机,所以不应直接从轴域列表中插入或删除轴域,而应使
用add_subplot()和add_axes()方法进行插入,并使用 delaxes()方法进行
删除。然而,你可以自由地遍历轴域列表或索引,来访问要自定义的 Axes实
例。下面是一个打开所有轴域网格的示例:
foraxinfig.axes:
ax.grid(True)
图形还拥有自己的文本,线条,补丁和图像,你可以使用它们直接添加基本类型。
图形的默认坐标系统简单地以像素(这通常不是你想要的)为单位,但你可以通过
设置你添加到图中的艺术家的 transform属性来控制它。
更有用的是『图形坐标系』,其中 (0,0)是图的左下角, (1,1)是图的右上
角,你可以通过将 Artist的变换设置为 fig.transFigure来获得:
In[191]:fig=plt.figure()
In[192]:l1=matplotlib.lines.Line2D([0,1],[0,1],
transform=fig.transFigure,figure=fig)
In[193]:l2=matplotlib.lines.Line2D([0,1],[1,0],
transform=fig.transFigure,figure=fig)
In[194]:fig.lines.extend([l1,l2])
In[195]:fig.canvas.draw()
艺术家教程
63

这里是图形可以包含的艺术家总结:
图形属性 描述
axes Axes实例的列表(包括 Subplot)
patch Rectangle背景
images FigureImages补丁的列表-用于原始像素显示
legends 图形 Legend实例的列表(不同于 Axes.legends)
lines 图形 Line2D实例的列表(很少使用,见 Axes.lines)
patches 图形补丁列表(很少使用,见 Axes.patches)
texts 图形 Text实例的列表
轴域容器
matplotlib.axes.Axes是matplotlib宇宙的中心-它包含绝大多数在一个图形
中使用的艺术家,并带有许多辅助方法来创建和添加这些艺术家本身,以及访问和
自定义所包含的艺术家的辅助方法。就像 Figure那样,它包含一
个Patchpatch,它是一个用于笛卡尔坐标的 Rectangle和一个用于极坐标
的Cirecle;这个补丁决定了绘图区域的形状,背景和边框:
艺术家教程
64

ax=fig.add_subplot(111)
rect=ax.patch#aRectangleinstance
rect.set_facecolor('green')
当调用绘图方法(例如通常是 plot())并传递数组或值列表时,该方法将创建一
个matplotlib.lines.Line2D()实例,将所有 Line2D属性作为关键字参数传
递,将该线条添加到 Axes.lines容器,并将其返回给你:
In[213]:x,y=np.random.rand(2,100)
In[214]:line,=ax.plot(x,y,'-',color='blue',linewidth=2)
plot返回一个线条列表,因为你可以传入多个 x,y偶对来绘制,我们将长度为
一的列表的第一个元素解构到 line变量中。该线条已添加到 Axes.lines列表
中:
In[229]:printax.lines
[<matplotlib.lines.Line2Dinstanceat0xd378b0c>]
与之类似,创建补丁的方法(如 bar())会创建一个矩形列表,将补丁添加
到Axes.patches列表中:
In[233]:n,bins,rectangles=ax.hist(np.random.randn(1000),50
,facecolor='yellow')
In[234]:rectangles
Out[234]:<alistof50Patchobjects>
In[235]:printlen(ax.patches)
你不应该直接将对象添加到 Axes.lines或Axes.patches列表,除非你确切知
道你在做什么,因为 Axes需要在它创建和添加对象做一些事情。它设
置Artist的figure和axes属性,以及默认 Axes变换(除非设置了变
换)。它还检查 Artist中包含的数据,来更新控制自动缩放的数据结构,以便
可以调整视图限制来包含绘制的数据。但是,你可以自己创建对象,并使用辅助方
法(如 add_line()和add_patch())将它们直接添加到 Axes。这里是一个
注释的交互式会话,说明正在发生什么:
艺术家教程
65

In[261]:fig=plt.figure()
In[262]:ax=fig.add_subplot(111)
#createarectangleinstance
In[263]:rect=matplotlib.patches.Rectangle((1,1),width=5,h
eight=12)
#bydefaulttheaxesinstanceisNone
In[264]:printrect.get_axes()
None
#andthetransformationinstanceissettothe"identitytransf
orm"
In[265]:printrect.get_transform()
<Affineobjectat0x13695544>
#nowweaddtheRectangletotheAxes
In[266]:ax.add_patch(rect)
#andnoticethattheax.add_patchmethodhassettheaxes
#instance
In[267]:printrect.get_axes()
Axes(0.125,0.1;0.775x0.8)
#andthetransformationhasbeensettoo
In[268]:printrect.get_transform()
<Affineobjectat0x15009ca4>
#thedefaultaxestransformationisax.transData
In[269]:printax.transData
<Affineobjectat0x15009ca4>
#noticethatthexlimitsoftheAxeshavenotbeenchanged
In[270]:printax.get_xlim()
(0.0,1.0)
#butthedatalimitshavebeenupdatedtoencompasstherectang
le
In[271]:printax.dataLim.bounds
(1.0,1.0,5.0,12.0)
#wecanmanuallyinvoketheauto-scalingmachinery
In[272]:ax.autoscale_view()
#andnowthexlimareupdatedtoencompasstherectangle
In[273]:printax.get_xlim()
(1.0,6.0)
#wehavetomanuallyforceafiguredraw
In[274]:ax.figure.canvas.draw()
艺术家教程
66

有非常多的 Axes辅助方法用于创建基本艺术家并将它们添加到他们各自的容器
中。下表总结了他们的一部分,他们创造的 Artist的种类,以及他们在哪里存
储它们。
辅助方法 艺术家 容器
ax.annotate-文本
标注 Annotate ax.texts
ax.bar-条形图 Rectangle ax.patches
ax.errorbar-误差
条形图
Line2D和
Rectangle
ax.lines和
ax.patches
ax.fill-共享区域 Polygon ax.patches
ax.hist-直方图 Rectangle ax.patches
ax.imshow-图像数据 AxesImage ax.images
ax.legend-轴域图例 Legend ax.legends
ax.plot-xy绘图 Line2D ax.lines
ax.scatter-散点图 PolygonCollection ax.collections
ax.text-文本 Text ax.texts
除了所有这些艺术家, Axes包含两个重要的艺术家容器: XAxis和YAxis,
它们处理刻度和标签的绘制。它们被存储为实例变量 xaxis和yaxis。
XAxis和YAxis容器将在下面详细介绍,但请注意, Axes包含许多辅助方
法,它们会将调用转发给 Axis实例,因此你通常不需要直接使用它们,除非你愿
意。例如,你可以使用 Axes辅助程序方法设置 XAxis刻度标签的字体大小:
forlabelinax.get_xticklabels():
label.set_color('orange')
下面是轴域所包含的艺术家的总结
艺术家教程
67

轴域属性 描述
artists Artist实例的列表
patch 用于轴域背景的 Rectangle实例
collections Collection实例的列表
images AxesImage的列表
legends Legend实例的列表
lines Line2D实例的列表
patches Patch实例的列表
texts Text实例的列表
xaxis matplotlib.axis.XAxis实例
yaxis matplotlib.axis.YAxis实例
轴容器
matplotlib.axis.Axis实例处理刻度线,网格线,刻度标签和轴标签的绘制。
你可以分别为y轴配置左和右刻度,为x轴分别配置上和下刻度。Axis还存储在
自动缩放,平移和缩放中使用的数据和视图间隔,以
及Locator和Formatter实例,它们控制刻度位置以及它们表示为字符串的方
式。
每个 Axis对象都包含一个 label属性(这是pylab在调
用xlabel()和ylabel()时修改的东西)以及主和次刻度的列表。刻度
是XTick和YTick实例,它包含渲染刻度和刻度标签的实际线条和文本基本类
型。因为刻度是按需动态创建的(例如,当平移和缩放时),你应该通过访问器方
法get_major_ticks()和get_minor_ticks()访问主和次刻度的列表。虽然刻
度包含所有下面要提及的基本类型, Axis方法包含访问器方法来返回刻度线,刻
度标签,刻度位置等:
艺术家教程
68

In[285]:axis=ax.xaxis
In[286]:axis.get_ticklocs()
Out[286]:array([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.
])
In[287]:axis.get_ticklabels()
Out[287]:<alistof10Textmajorticklabelobjects>
#notetherearetwiceasmanyticklinesaslabelsbecauseby
#defaultthereareticklinesatthetopandbottombutonlyt
ick
#labelsbelowthexaxis;thiscanbecustomized
In[288]:axis.get_ticklines()
Out[288]:<alistof20Line2Dticklinesobjects>
#bydefaultyougetthemajorticksback
In[291]:axis.get_ticklines()
Out[291]:<alistof20Line2Dticklinesobjects>
#butyoucanalsoaskfortheminorticks
In[292]:axis.get_ticklines(minor=True)
Out[292]:<alistof0Line2Dticklinesobjects>
下面是 Axis的一些有用的访问器方法的总结(它们拥有相应的 setter,
如set_major_formatter)。
艺术家教程
69

访问器方法 描述
get_scale 轴的比例,例如 'log'或'linear'
get_view_interval 轴视图范围的内部实例
get_data_interval 轴数据范围的内部实例
get_gridlines 轴的网格线列表
get_label 轴标签- Text实例
get_ticklabels Text实例的列表-关键字`minor=True False`
get_ticklines Line2D实例的列表-关键字`minor=True False`
get_ticklocs Tick位置的列表-关键字`minor=True False`
get_major_locator 用于主刻度
的matplotlib.ticker.Locator实例
get_major_formatter 用于主刻度
的matplotlib.ticker.Formatter实例
get_minor_locator 用于次刻度
的matplotlib.ticker.Locator实例
get_minor_formatter 用于次刻度
的matplotlib.ticker.Formatter实例
get_major_ticks 用于主刻度的 Tick实例列表
get_minor_ticks 用于次刻度的 Tick实例列表
grid 为主或次刻度打开或关闭网格
这里是个例子,出于美观不太推荐,它自定义了轴域和刻度属性。
艺术家教程
70

importnumpyasnp
importmatplotlib.pyplotasplt
#plt.figurecreatesamatplotlib.figure.Figureinstance
fig=plt.figure()
rect=fig.patch#arectangleinstance
rect.set_facecolor('lightgoldenrodyellow')
ax1=fig.add_axes([0.1,0.3,0.4,0.4])
rect=ax1.patch
rect.set_facecolor('lightslategray')
forlabelinax1.xaxis.get_ticklabels():
#labelisaTextinstance
label.set_color('red')
label.set_rotation(45)
label.set_fontsize(16)
forlineinax1.yaxis.get_ticklines():
#lineisaLine2Dinstance
line.set_color('green')
line.set_markersize(25)
line.set_markeredgewidth(3)
plt.show()
艺术家教程
71

刻度容器
matplotlib.axis.Tick是我们从 Figure到Axes再到 Axis再到 Tick的
最终的容器对象。 Tick包含刻度和网格线的实例,以及上侧和下侧刻度的标签实
例。每个都可以直接作为 Tick的属性访问。此外,也有用于确定上标签和刻度
是否对应 x轴,以及右标签和刻度是否对应 y轴的布尔变量。
刻度属性 描述
tick1line Line2D实例
tick2line Line2D实例
gridline Line2D实例
label1 Text实例
label2 Text实例
gridOn 确定是否绘制刻度线的布尔值
tick1On 确定是否绘制主刻度线的布尔值
tick2On 确定是否绘制次刻度线的布尔值
label1On 确定是否绘制主刻度标签的布尔值
label2On 确定是否绘制次刻度标签的布尔值
这里是个例子,使用美元符号设置右侧刻度,并在 y轴右侧将它们设成绿色。
importnumpyasnp
importmatplotlib.pyplotasplt
importmatplotlib.tickerasticker
#Fixingrandomstateforreproducibility
np.random.seed(19680801)
fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(100*np.random.rand(20))
formatter=ticker.FormatStrFormatter('$%1.2f')
ax.yaxis.set_major_formatter(formatter)
fortickinax.yaxis.get_major_ticks():
tick.label1On=False
tick.label2On=True
tick.label2.set_color('green')
plt.show()
艺术家教程
72

艺术家教程
73

图例指南
原文:Legendguide
译者:飞龙
协议:CCBY-NC-SA4.0
此图例指南是 legend()中可用文档的扩展-请在继续阅读本指南之前确保你熟悉
该文档(见篇尾)的内容。
本指南使用一些常见术语,为了清楚起见,这些术语在此处进行说明:
图例条目
图例由一个或多个图例条目组成。一个条目由一个键和一个标签组成。
图例键
每个图例标签左侧的彩色/图案标记。
图例标签
描述由键表示的句柄的文本。
图例句柄
用于在图例中生成适当条目的原始对象。
控制图例条目
不带参数调用 legend()会自动获取图例句柄及其相关标签。此函数等同于:
handles,labels=ax.get_legend_handles_labels()
ax.legend(handles,labels)
get_legend_handles_labels()函数返回轴域上存在的句柄/艺术家的列表,这
些句柄/艺术家可以用于为结果图例生成条目-但值得注意的是,并非所有艺术家都
可以添加到图例中,这种情况下会创建『代理』(请参阅特地为添加到图例创建艺
术家(也称为代理艺术家),来了解更多详细信息)。
为了完全控制要添加到图例的内容,通常将适当的句柄直接传递给 legend():
line_up,=plt.plot([1,2,3],label='Line2')
line_down,=plt.plot([3,2,1],label='Line1')
plt.legend(handles=[line_up,line_down])
图例指南
74

在某些情况下,不可能设置句柄的标签,因此可以将标签列表传递给 legend():
line_up,=plt.plot([1,2,3],label='Line2')
line_down,=plt.plot([3,2,1],label='Line1')
plt.legend([line_up,line_down],['LineUp','LineDown'])
特地为添加到图例创建艺术家(也称为代理艺术家)
并非所有的句柄都可以自动转换为图例条目,因此通常需要创建一个可转换的艺术
家。图例句柄不必存在于被用到的图像或轴域上。
假设我们想创建一个图例,其中有一些数据表示为红色:
importmatplotlib.patchesasmpatches
importmatplotlib.pyplotasplt
red_patch=mpatches.Patch(color='red',label='Thereddata')
plt.legend(handles=[red_patch])
plt.show()
除了创建一个色块之外,有许多受支持的图例句柄,我们可以创建一个带有标记的
线条:
图例指南
75

importmatplotlib.linesasmlines
importmatplotlib.pyplotasplt
blue_line=mlines.Line2D([],[],color='blue',marker='*',
markersize=15,label='Bluestars')
plt.legend(handles=[blue_line])
plt.show()
图例位置
图例的位置可以通过关键字参数 loc指定。详细信息请参阅 legend()的文档。
bbox_to_anchor关键字可让用户手动控制图例布局。例如,如果你希望轴域图
例位于图像的右上角而不是轴域的边角,则只需指定角的位置以及该位置的坐标
系:
plt.legend(bbox_to_anchor=(1,1),
bbox_transform=plt.gcf().transFigure)
自定义图例位置的更多示例:
importmatplotlib.pyplotasplt
plt.subplot(211)
plt.plot([1,2,3],label="test1")
plt.plot([3,2,1],label="test2")
#将图例放到这个子图上方,
#扩展自身来完全利用提供的边界框。
plt.legend(bbox_to_anchor=(0.,1.02,1.,.102),loc=3,
ncol=2,mode="expand",borderaxespad=0.)
plt.subplot(223)
plt.plot([1,2,3],label="test1")
plt.plot([3,2,1],label="test2")
#将图例放到这个小型子图的右侧
plt.legend(bbox_to_anchor=(1.05,1),loc=2,borderaxespad=0.)
plt.show()
图例指南
76

相同轴域内的多个图例
有时,在多个图例之间分割图例条目会更加清晰。虽然直觉上的做法可能是多次调
用legend()函数,但你会发现轴域上只存在一个图例。这样做是为了可以重复
调用 legend(),将图例更新为轴域上的最新句柄,因此要保留旧的图例实例,我
们必须将它们手动添加到轴域中:
importmatplotlib.pyplotasplt
line1,=plt.plot([1,2,3],label="Line1",linestyle='--')
line2,=plt.plot([3,2,1],label="Line2",linewidth=4)
#为第一个线条创建图例
first_legend=plt.legend(handles=[line1],loc=1)
#手动将图例添加到当前轴域
ax=plt.gca().add_artist(first_legend)
#为第二个线条创建另一个图例
plt.legend(handles=[line2],loc=4)
plt.show()
图例指南
77

图例处理器
为了创建图例条目,将句柄作为参数提供给适当的 HandlerBase子类。处理器子
类的选择由以下规则确定:
使用 handler_map关键字中的值更新 get_legend_handler_map()。
检查句柄是否在新创建的 handler_map中。
检查句柄的类型是否在新创建的 handler_map中。
检查句柄的 mro中的任何类型是否在新创建的 handler_map中。
处于完整性,这个逻辑大多在 get_legend_handler()中实现。
所有这些灵活性意味着我们可以使用一些必要的钩子,为我们自己的图例键类型实
现自定义处理器。
使用自定义处理器的最简单的例子是,实例化一个现有的 HandlerBase子类。为
了简单起见,让我们选择 matplotlib.legend_handler.HandlerLine2D,它接
受numpoints参数(出于便利,注意 numpoints是legend()函数上的一个关
键字)。然后我们可以将实例的字典作为关键字 handler_map传给 legend。
图例指南
78

importmatplotlib.pyplotasplt
frommatplotlib.legend_handlerimportHandlerLine2D
line1,=plt.plot([3,2,1],marker='o',label='Line1')
line2,=plt.plot([1,2,3],marker='o',label='Line2')
plt.legend(handler_map={line1:HandlerLine2D(numpoints=4)})
如你所见, Line1现在有4个标记点, Line2有两个(默认值)。尝试上面
的代码,只需将字典的键从 line1更改为type(line) 。注意现在两个Line2D`实例
都拥有了4个标记。
除了用于复杂的绘图类型的处理器,如误差条,茎叶图和直方图,默认
的handler_map有一个特殊的元组处理器( HandlerTuple),它简单地在顶部
一一绘制给定元组中每个项目的句柄。以下示例演示如何将两个图例的键相互叠
加:
图例指南
79

importmatplotlib.pyplotasplt
fromnumpy.randomimportrandn
z=randn(10)
red_dot,=plt.plot(z,"ro",markersize=15)
#将白色十字放置在一些数据上
white_cross,=plt.plot(z[:5],"w+",markeredgewidth=3,markersi
ze=15)
plt.legend([red_dot,(red_dot,white_cross)],["AttrA","AttrA
+B"])
实现自定义图例处理器
可以实现自定义处理器,将任何句柄转换为图例的键(句柄不必要
是matplotlibartist)。处理器必须实现 legend_artist方法,该方法为要使
用的图例返回单个艺术家。有关 legend_artist的详细信息,请参
阅legend_artist()。
图例指南
80

importmatplotlib.pyplotasplt
importmatplotlib.patchesasmpatches
classAnyObject(object):
pass
classAnyObjectHandler(object):
deflegend_artist(self,legend,orig_handle,fontsize,handl
ebox):
x0,y0=handlebox.xdescent,handlebox.ydescent
width,height=handlebox.width,handlebox.height
patch=mpatches.Rectangle([x0,y0],width,height,face
color='red',
edgecolor='black',hatch='xx'
,lw=3,
transform=handlebox.get_trans
form())
handlebox.add_artist(patch)
returnpatch
plt.legend([AnyObject()],['Myfirsthandler'],
handler_map={AnyObject:AnyObjectHandler()})
或者,如果我们想要接受全局的 AnyObject实例,而不想一直手动设
置handler_map关键字,我们可以注册新的处理器:
图例指南
81

frommatplotlib.legendimportLegend
Legend.update_default_handler_map({AnyObject:AnyObjectHandler()
})
虽然这里的功能十分清楚,请记住,有很多已实现的处理器,你想实现的目标可能
易于使用现有的类实现。例如,要生成椭圆的图例键,而不是矩形键:
frommatplotlib.legend_handlerimportHandlerPatch
importmatplotlib.pyplotasplt
importmatplotlib.patchesasmpatches
classHandlerEllipse(HandlerPatch):
defcreate_artists(self,legend,orig_handle,
xdescent,ydescent,width,height,fontsi
ze,trans):
center=0.5*width-0.5*xdescent,0.5*height-0.5
*ydescent
p=mpatches.Ellipse(xy=center,width=width+xdescent,
height=height+ydescent)
self.update_prop(p,orig_handle,legend)
p.set_transform(trans)
return[p]
c=mpatches.Circle((0.5,0.5),0.25,facecolor="green",
edgecolor="red",linewidth=3)
plt.gca().add_patch(c)
plt.legend([c],["Anellipse,notarectangle"],
handler_map={mpatches.Circle:HandlerEllipse()})
图例指南
82

使用图例的现有示例
这里是一个不太详尽的示例列表,涉及以各种方式使用的图例:
lines_bars_and_markers示例代码: scatter_with_legend.py
API示例代码: legend_demo.py
pylab_examples示例代码: contourf_hatching.py
pylab_examples示例代码: figlegend_demo.py
pylab_examples示例代码: finance_work2.py
pylab_examples示例代码: scatter_symbol.py
matplotlib.pyplot.legend(*args,**kwargs)文档
在轴域上放置一个图例。
为了为轴域上已经存在的线条(例如通过绘图)制作图例,只需使用字符串的可迭
代对象(每个图例条目对应一个字符串)调用此函数。例如:
ax.plot([1,2,3])
ax.legend(['Asimpleline'])
图例指南
83

但是,为了使『标签』和图例元素实例保持一致,最好在艺术家创建时指定标签,
或者通过调用艺术家的 set_label()方法:
line,=ax.plot([1,2,3],label='Inlinelabel')
#通过调用该方法覆写标签
line.set_label('Labelviamethod')
ax.legend()
通过定义以下划线开头的标签,可以从图例元素自动选择中排除特定线条。这对于
所有艺术家都是默认的,因此不带任何参数调用 legend(),并且没有手动设置标
签会导致没有绘制图例。
为了完全控制哪些艺术家拥有图例条目,可以传递拥有图例的艺术家的可迭代对
象,然后是相应图例标签的可迭代对象:
legend((line1,line2,line3),('label1','label2','label3'))
参数
loc:整数、字符串或者浮点偶对,默认为 'upperright'。
图例的位置。可能的代码是:
位置字符串 位置代码
'best' 0
'upperright' 1
'upperleft' 2
'lowerleft' 3
'lowerright' 4
'right' 5
'centerleft' 6
'centerright' 7
'lowercenter' 8
'uppercenter' 9
'center' 10
或者,可以是一个二元组,提供图例的距离左下角的 x,y坐标(在这种情况
下, bbox_to_anchor将被忽略)。
bbox_to_anchor:matplotlib.transforms.BboxBase示例或者浮点元组。
图例指南
84

在bbox_transform坐标(默认轴域坐标)中为图例指定任意位置。
例如,要将图例的右上角放在轴域中心,可以使用以下关键字:
loc='upperright',bbox_to_anchor=(0.5,0.5)
ncol:整数。
图例的列数,默认为1。
prop:None、matplotlib.font_manager.FontProperties或者字典。
图例的字体属性,如果为 None(默认),会使用当前
的matplotlib.rcParams。
fontsize:整数、浮点或
者{‘xx-small’,‘x-small’,‘small’,‘medium’,‘large’,‘x-large’,‘xx-large’}
。
控制图例的字体大小。如果值为数字,则大小将为绝对字体大小(以磅为单位)。
字符串值相对于当前默认字体大小。此参数仅在未指定 prop的情况下使用。
numpoints:None或者整数。
为线条/matplotlib.lines.Line2D创建图例条目时,图例中的标记点数。默认
值为 None,它将从 legend.numpointsrcParam中获取值。
scatterpoints:None或者整数。
为散点图/matplotlib.collections.PathCollection创建图例条目时,图例中
的标记点数。默认值为 None,它将从 legend.scatterpointsrcParam中获
取值。
scatteryoffsets:浮点的可迭代对象。
为散点图图例条目创建的标记的垂直偏移量(相对于字体大小)。0.0是在图例文
本的底部,1.0是在顶部。为了将所有标记绘制在相同的高度,请设置
为[0.5]。默认值为 [0.375,0.5,0.3125]。
markerscale:None、整数或者浮点。
图例标记对于原始绘制的标记的相对大小。默认值为 None,它将
从legend.markerscalercParam中获取值。
markerfirst: [True|False]
如果为 True,则图例标记位于图例标签的左侧,如果为 False,图例标记位于
图例标签的右侧。
frameon:None或布尔值
图例指南
85

控制是否应在图例周围绘制框架。默认值为 None,它将从 legend.frameon
rcParam中获取值。
fancybox:None或布尔值
控制是否应在构成图例背景的 FancyBboxPatch周围启用圆边。默认值
为None,它将从 legend.fancyboxrcParam中获取值。
shadow:None或布尔值
控制是否在图例后面画一个阴影。默认值为 None,它将从 legend.shadow
rcParam中获取值。
framealpha:None或浮点
控制图例框架的Alpha透明度。默认值为 None,它将从 legend.framealpha
rcParam中获取值。
mode:{"expand",None}
如果 mode设置为 "expand",图例将水平扩展来填充轴域区域(如果定义图例
的大小,则为 bbox_to_anchor)。
bbox_transform:None或者 matplotlib.transforms.Transform
边界框的变换( bbox_to_anchor)。对于 None值(默认),将使
用Axes的transAxes变换。
title:字符串或者 None
图例的标题,默认没有标题( None)。
borderpad:浮点或 None
图例边框的内边距。以字体大小为单位度量。默认值为 None,它将
从legend.borderpadrcParam中获取值。
labelspacing:浮点或 None
图例条目之间的垂直间距。以字体大小为单位度量。默认值为 None,它将
从legend.labelspacingrcParam中获取值。
handlelength:浮点或 None
图例句柄的长度。以字体大小为单位度量。默认值为 None,它将
从legend.handlelengthrcParam取值。
handletextpad:浮点或 None
图例句柄和文本之间的间距。以字体大小为单位度量。默认值为 None,它将
从legend.handletextpadrcParam中获取值。
borderaxespad:浮点或 None
图例指南
86

轴和图例边框之间的间距。以字体大小为单位度量。默认值为 None,它将
从legend.borderaxespadrcParam中获取值。
columnspacing:浮点或 None
列间距。以字体大小为单位度量。默认值为 None,它将
从legend.columnspacingrcParam中获取值。
handler_map:字典或 None
自定义字典,用于将实例或类型映射到图例处理器。这个 handler_map会更新
在matplotlib.legend.Legend.get_legend_handler_map()中获得的默认处理
器字典。
图例指南
87

变换教程
原文:TransformationsTutorial
译者:飞龙
协议:CCBY-NC-SA4.0
像任何图形包一样,matplotlib建立在变换框架之上,以便在坐标系,用户数据坐
标系,轴域坐标系,图形坐标系和显示坐标系之间轻易变换。在95%的绘图中,
你不需要考虑这一点,因为它发生在背后,但随着你接近自定义图形生成的极限,
它有助于理解这些对象,以便可以重用matplotlib提供给你的现有变换,或者创建
自己的变换(见 matplotlib.transforms)。下表总结了现有的坐标系,你应
该在该坐标系中使用的变换对象,以及该系统的描述。在『变换对象』一列
中, ax是Axes实例, fig是一个图形实例。
坐
标
系
变换对象 描述
数
据ax.transData 用户数据坐标系,由 xlim和ylim控制
轴
域ax.transAxes 轴域坐标系; (0,0)是轴域左下角, (1,1)是轴域右
上角
图
形fig.transFigure 图形坐标系; (0,0)是图形左下角, (1,1)是图形右
上角
显
示None
这是显示器的像素坐标系; (0,0)是显示器的左下
角, (width,height)是显示器的右上角,以像素为
单位。或者,可以使用恒等变换
(matplotlib.transforms.IdentityTransform()
来代替 None。
上表中的所有变换对象都接受以其坐标系为单位的输入,并将输入变换到显示坐标
系。这就是为什么显示坐标系没有『变换对象』的原因-它已经以显示坐标为单位
了。变换也知道如何反转自身,从显示返回自身的坐标系。这在处理来自用户界
面的事件(通常发生在显示空间中),并且你想知道数据坐标系中鼠标点击或按键
按下的位置时特别有用。
数据坐标
让我们从最常用的坐标,数据坐标系开始。每当向轴域添加数据时,matplotlib会
更新数据对象, set_xlim()和set_ylim()方法最常用于更新。例如,在下图
中,数据的范围在 x轴上为从0到10,在 y轴上为从-1到1。
变换教程
88

importnumpyasnp
importmatplotlib.pyplotasplt
x=np.arange(0,10,0.005)
y=np.exp(-x/2.)*np.sin(2*np.pi*x)
fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(x,y)
ax.set_xlim(0,10)
ax.set_ylim(-1,1)
plt.show()
你可以使用 ax.transData实例将数据变换为显示坐标系,无论是单个点或是一
系列点,如下所示:
变换教程
89

In[14]:type(ax.transData)
Out[14]:<class'matplotlib.transforms.CompositeGenericTransform
'>
In[15]:ax.transData.transform((5,0))
Out[15]:array([335.175,247.])
In[16]:ax.transData.transform([(5,0),(1,2)])
Out[16]:
array([[335.175,247.],
[132.435,642.2]])
你可以使用 inverted()方法创建一个变换,从显示坐标变换为数据坐标:
In[41]:inv=ax.transData.inverted()
In[42]:type(inv)
Out[42]:<class'matplotlib.transforms.CompositeGenericTransform
'>
In[43]:inv.transform((335.175,247.))
Out[43]:array([5.,0.])
如果你一直关注本教程,如果你的窗口大小或dpi设置不同,显示坐标的确切值可
能会有所不同。同样,在下面的图形中,在ipython会话中,由显示标记的点可能
并不相同,因为文档图形大小默认值是不同的。
变换教程
90

注意
如果在GUI后端中运行上述示例中的源代码,你还可能发现数据和显示标注的
两个箭头不会指向完全相同的点。这是因为显示点是在显示图形之前计算的,
并且GUI后端可以在创建图形时稍微调整图形大小。如果你自己调整图的大
小,效果更明显。这是你很少想要处理显示空间的一个很好的原因,但是你可
以连接到 'on_draw'事件来更新图上的图坐标;请参阅事件处理和选择。
当你更改轴的 x或y的范围时,将更新数据范围,以便变换生成新的显示点。
注意,当我们只是改变 ylim,只有 y显示坐标改变,当我们改变 xlim也同
理。我们在谈论Bbox时会深入。
In[54]:ax.transData.transform((5,0))
Out[54]:array([335.175,247.])
In[55]:ax.set_ylim(-1,2)
Out[55]:(-1,2)
In[56]:ax.transData.transform((5,0))
Out[56]:array([335.175,181.13333333])
In[57]:ax.set_xlim(10,20)
Out[57]:(10,20)
In[58]:ax.transData.transform((5,0))
Out[58]:array([-171.675,181.13333333])
变换教程
91

轴域坐标
在数据坐标系之后,轴域可能是第二有用的坐标系。这里,点 (0,0)是轴域或子
图的左下角, (0.5,0.5)是中心, (1.0,1.0)是右上角。你还可以引用范围之
外的点,因此 (-0.1,1.1)位于轴的左上方。此坐标系在将文本放置在轴中时非
常有用,因为你通常需要在固定的位置(例如,轴域窗格的左上角)放置文本气
泡,并且在平移或缩放时保持该位置固定。这里是一个简单的例子,创建四个面
板,并将他们标记为 'A','B','C','D',你经常在期刊上看到它们。
你也可以在轴坐标系中创建线条或者补丁,但是以我的经验,这比使
用ax.transAxes放置文本更不实用。尽管如此,这里是一个愚蠢的例子,它在
数据空间中绘制了一些随机点,并且覆盖在一个半透明的圆上面,这个圆以轴域的
中心为圆心,半径为轴域的四分之一。-如果你的轴域不保留高宽比
(见 set_aspect()),它将看起来像一个椭圆。使用平移/缩放工具移动,或
手动更改数据的 xlim和ylim,你将看到数据移动,但圆将保持固定,因为它
不在数据坐标中,并且将始终保持在轴域的中心。
变换教程
92

混合变换
在数据与轴域坐标混合的混合坐标空间中绘制是非常实用的,例如创建一个水平跨
度,突出 y数据的一些区域但横跨 x轴,而无论数据限制,平移或缩放级别等。
实际上这些混合线条和跨度非常有用,我们已经内置了一些函数来使它们容易绘制
(参见 axhline(),axvline(),axhspan(),axvspan()),但是为了
教学目的,我们使用混合变换实现这里的水平跨度。这个技巧只适用于可分离的变
换,就像你在正常的笛卡尔坐标系中看到的,但不能为不可分离的变换,
如PolarTransform(极坐标变换)。
变换教程
93

importnumpyasnp
importmatplotlib.pyplotasplt
importmatplotlib.patchesaspatches
importmatplotlib.transformsastransforms
fig=plt.figure()
ax=fig.add_subplot(111)
x=np.random.randn(1000)
ax.hist(x,30)
ax.set_title(r'$\sigma=1\/\dots\/\sigma=2$',fontsize=16)
#thexcoordsofthistransformationaredata,andthe
#ycoordareaxes
trans=transforms.blended_transform_factory(
ax.transData,ax.transAxes)
#highlightthe1..2stddevregionwithaspan.
#Wewantxtobeindatacoordinatesandyto
#spanfrom0..1inaxescoords
rect=patches.Rectangle((1,0),width=1,height=1,
transform=trans,color='yellow',
alpha=0.5)
ax.add_patch(rect)
plt.show()
变换教程
94

注
混合变换非常有用,其中 x为数据坐标而 y为轴域坐标,我们拥有辅助方法
来返回内部使用的版本mpl,用于绘制 ticks,ticklabels以及其他。方
法
是matplotlib.axes.Axes.get_xaxis_transform()和matplotlib.axes.Axes.get_yaxis_transform()
。因此,在上面的示例中, blended_transform_factory()的调用可以替
换为 get_xaxis_transform:
trans=ax.get_xaxis_transform()
使用偏移变换来创建阴影效果
变换的一个用法,是创建偏离另一变换的新变换,例如,放置一个对象,相对于另
一对象有一些偏移。通常,你希望物理尺寸上有一些移位,例如以点或英寸,而不
是数据坐标为单位,以便移位效果在不同的缩放级别和dpi设置下保持不变。
偏移的一个用途是创建一个阴影效果,其中你绘制一个与第一个相同的对象,刚好
在它的右边和下面,调整 zorder来确保首先绘制阴影,然后绘制对象,阴影在它
之上。变换模块具有辅助变换 ScaledTranslation。它可以这样来实例化:
trans=ScaledTranslation(xt,yt,scale_trans)
变换教程
95

其中 xt和yt是变换的偏移, scale_trans是变换,在应用偏移之前的变换期
间缩放 xt和yt。一个典型的用例是,将图形的 fig.dpi_scale_trans变换
用于 scale_trans参数,来在实现最终的偏移之前,首先将以点为单位
的xt和yt缩放到显示空间。DPI和英寸偏移是常见的用例,我们拥有一个特
殊的辅助函数,来在 matplotlib.transforms.offset_copy()中创建它,它返
回一个带有附加偏移的新变换。但在下面的示例中,我们将自己创建偏移变换。
注意使用加法运算符:
offset=transforms.ScaledTranslation(dx,dy,
fig.dpi_scale_trans)
shadow_transform=ax.transData+offset
这里显示了,可以使用加法运算符将变换链起来。该代码表示:首先应用数据变
换ax.transData,然后由 dx和dy点翻译数据。在排版中,一个点是1/72
英寸,通过以点为单位指定偏移,你的图形看起来是一样的,无论所保存的dpi分
辨率。
importnumpyasnp
importmatplotlib.pyplotasplt
importmatplotlib.patchesaspatches
importmatplotlib.transformsastransforms
fig=plt.figure()
ax=fig.add_subplot(111)
#makeasimplesinewave
x=np.arange(0.,2.,0.01)
y=np.sin(2*np.pi*x)
line,=ax.plot(x,y,lw=3,color='blue')
#shifttheobjectover2points,anddown2points
dx,dy=2/72.,-2/72.
offset=transforms.ScaledTranslation(dx,dy,
fig.dpi_scale_trans)
shadow_transform=ax.transData+offset
#nowplotthesamedatawithouroffsettransform;
#usethezordertomakesurewearebelowtheline
ax.plot(x,y,lw=3,color='gray',
transform=shadow_transform,
zorder=0.5*line.get_zorder())
ax.set_title('creatingashadoweffectwithanoffsettransform'
)
plt.show()
变换教程
96

变换流水线
我们在本教程中一直使用的 ax.transData变换是三种不同变换的组合,它们构
成从数据到显示坐标的变换流水线。MichaelDroettboom实现了变换框架,提供
了一个干净的API,它隔离了在极坐标和对数坐标图中发生的非线性投影和尺度,
以及在平移和缩放时发生的线性仿射变换。这里有一个效率问题,因为你可以平移
和放大你的轴域,它会影响仿射变换,但你可能不需要计算潜在的昂贵的非线性比
例或简单的导航事件的投影。也可以将仿射变换矩阵相乘在一起,然后在一步之中
将它们应用于坐标。这对所有可能的变换不都是有效的。
这里是在 ax.transData实例在基本可分离的 Axes类中的定义方式。
self.transData=self.transScale+(self.transLimits+self.tran
sAxes)
我们已经在 Axes坐标中引入了上面的 transAxes实例,它将轴或子图边界框
的(0,0),(1,1)角映射到显示空间,所以让我们看看这两个部分。
self.transLimits是从数据到轴域坐标的变换;也就是说,它将你的视
图xlim和ylim映射到轴域单位空间(然后 transAxes将该单位空间用于显示
空间)。我们可以在这里看到这一点:
变换教程
97

In[80]:ax=subplot(111)
In[81]:ax.set_xlim(0,10)
Out[81]:(0,10)
In[82]:ax.set_ylim(-1,1)
Out[82]:(-1,1)
In[84]:ax.transLimits.transform((0,-1))
Out[84]:array([0.,0.])
In[85]:ax.transLimits.transform((10,-1))
Out[85]:array([1.,0.])
In[86]:ax.transLimits.transform((10,1))
Out[86]:array([1.,1.])
In[87]:ax.transLimits.transform((5,0))
Out[87]:array([0.5,0.5])
而且我们可以使用相同的反转变换,从轴域单位坐标变换回数据坐标。
In[90]:inv.transform((0.25,0.25))
Out[90]:array([2.5,-0.5])
最后一个是 self.transScale属性,它负责数据的可选非线性缩放,例如对数轴
域。当Axes初始化时,这只是设置为恒等变换,因为基本的matplotlib轴域具有
线性缩放,但是当你调用对数缩放函数如 semilogx()或使用 set_xscale显式
设置为对数时, ax.transScale属性为处理非线性投影而设置。缩放变换是相
应xaxis和yaxis的Axis实例的属性。例如,当调
用ax.set_xscale('log')时, xaxis会将其缩放更新
为matplotlib.scale.LogScale实例。
对于不可分离的轴域, PolarAxes,还有一个要考虑的部分,投影变换。
matplotlib.projections.polar.PolarAxes的transData类似于典型的可分
离matplotlib轴域,带有一个额外的部分, transProjection:
self.transData=self.transScale+self.transProjection+\
(self.transProjectionAffine+self.transAxes)
transProjection将来自空间的投影,例如,地图数据的纬度和经度,或极坐标
数据的半径和极角,处理为可分离的笛卡尔坐标系。
在matplotlib.projections包中有几个投影示例,深入了解的最好方法是打开
这些包的源代码,看看如何自己制作它,因为matplotlib支持可扩展的轴域和投
影。MichaelDroettboom提供了一个创建一个锤投影轴域的很好的教程示例;请
参阅api示例代码: custom_projection_example.py。
变换教程
98

变换教程
99

路径教程
原文:PathTutorial
译者:飞龙
协议:CCBY-NC-SA4.0
位于所有 matplotlib.patch对象底层的对象是 Path,它支
持moveto,lineto,curveto命令的标准几个,来绘制由线段和样条组成的
简单和复合轮廓。路径由 (x,y)顶点的 (N,2)数组,以及路径代码的长度为N
的数组实例化。例如,为了绘制 (0,0)到(1,1)的单位矩形,我们可以使用这
个代码:
importmatplotlib.pyplotasplt
frommatplotlib.pathimportPath
importmatplotlib.patchesaspatches
verts=[
(0.,0.),#left,bottom
(0.,1.),#left,top
(1.,1.),#right,top
(1.,0.),#right,bottom
(0.,0.),#ignored
]
codes=[Path.MOVETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.CLOSEPOLY,
]
path=Path(verts,codes)
fig=plt.figure()
ax=fig.add_subplot(111)
patch=patches.PathPatch(path,facecolor='orange',lw=2)
ax.add_patch(patch)
ax.set_xlim(-2,2)
ax.set_ylim(-2,2)
plt.show()
路径教程
100

下面的路径代码会被接受:
代码 顶点 描述
STOP 1(被忽略) 标志整个路径终点的标记(当前不需要
或已忽略)
MOVETO 1提起笔并移动到指定顶点
LINETO 1从当前位置向指定顶点画线
CURVE3 2(一个控制点,
一个终点)
从当前位置,以给定控制点向给定端点
画贝塞尔曲线
CURVE4 3(两个控制点,
一个终点)
从当前位置,以给定控制点向给定端点
画三次贝塞尔曲线
CLOSEPOLY 1(点自身被忽
略) 向当前折线的起点画线
贝塞尔示例
一些路径组件需要以多个顶点来指定:例如 CURVE3是具有一个控制点和一个端点
的贝塞尔曲线, CURVE4具有用做两个控制点和端点的三个顶点。下面的示例显
示了 CURVE4贝塞尔曲线-贝塞尔曲线将包含在起始点,两个控制点和终点的凸包
中:
路径教程
101

importmatplotlib.pyplotasplt
frommatplotlib.pathimportPath
importmatplotlib.patchesaspatches
verts=[
(0.,0.),#P0
(0.2,1.),#P1
(1.,0.8),#P2
(0.8,0.),#P3
]
codes=[Path.MOVETO,
Path.CURVE4,
Path.CURVE4,
Path.CURVE4,
]
path=Path(verts,codes)
fig=plt.figure()
ax=fig.add_subplot(111)
patch=patches.PathPatch(path,facecolor='none',lw=2)
ax.add_patch(patch)
xs,ys=zip(*verts)
ax.plot(xs,ys,'x--',lw=2,color='black',ms=10)
ax.text(-0.05,-0.05,'P0')
ax.text(0.15,1.05,'P1')
ax.text(1.05,0.85,'P2')
ax.text(0.85,-0.05,'P3')
ax.set_xlim(-0.1,1.1)
ax.set_ylim(-0.1,1.1)
plt.show()
路径教程
102

复合路径
所有在matplotlib,Rectangle,Circle,Polygon等中的简单补丁原语都是用简单
的路径实现的。通过使用复合路径,通常可以更有效地实现绘制函数,
如hist()和bar(),它们创建了许多原语,例如一堆 Rectangle,通常可使
用复合路径来实现。 bar创建一个矩形列表,而不是一个复合路径,很大程度上
出于历史原因:路径代码是比较新的, bar在它之前就存在。虽然我们现在可以
改变它,但它会破坏旧的代码,所以如果你需要为了效率,在你自己的代码中这样
做,例如,创建动画条形图,在这里我们将介绍如何创建复合路径,替换 bar中
的功能。
我们将通过为每个直方图的条形创建一系列矩形,来创建直方图图表:矩形宽度是
条形的宽度,矩形高度是该条形中的数据点数量。首先,我们将创建一些随机的正
态分布数据并计算直方图。因为numpy返回条形边缘而不是中心,所以下面的示
例中 bins的长度比 n的长度大1:
#histogramourdatawithnumpy
data=np.random.randn(1000)
n,bins=np.histogram(data,100)
我们现在将提取矩形的角。下面的每个 left,bottom等数组长度
为len(n),其中 n是每个直方图条形的计数数组:
路径教程
103

#getthecornersoftherectanglesforthehistogram
left=np.array(bins[:-1])
right=np.array(bins[1:])
bottom=np.zeros(len(left))
top=bottom+n
现在我们必须构造复合路径,它由每个矩形的一系
列MOVETO,LINETO和CLOSEPOLY组成。对于每个矩形,我们需要5个顶
点:一个代表 MOVETO,三个代表 LINETO,一个代表 CLOSEPOLY。如上表所
示, closepoly的顶点被忽略,但我们仍然需要它来保持代码与顶点对齐:
nverts=nrects*(1+3+1)
verts=np.zeros((nverts,2))
codes=np.ones(nverts,int)*path.Path.LINETO
codes[0::5]=path.Path.MOVETO
codes[4::5]=path.Path.CLOSEPOLY
verts[0::5,0]=left
verts[0::5,1]=bottom
verts[1::5,0]=left
verts[1::5,1]=top
verts[2::5,0]=right
verts[2::5,1]=top
verts[3::5,0]=right
verts[3::5,1]=bottom
剩下的就是创建路径了,将其添加到 PathPatch,将其添加到我们的轴域:
barpath=path.Path(verts,codes)
patch=patches.PathPatch(barpath,facecolor='green',
edgecolor='yellow',alpha=0.5)
ax.add_patch(patch)
结果为:
路径教程
104

路径教程
105

路径效果指南
原文:Patheffectsguide
译者:飞龙
协议:CCBY-NC-SA4.0
Matplotlib的patheffects模块提供了一些功能,用于将多个绘制层次应用到任
何艺术家,并可以通过路径呈现。
可以对其应用路径效果的艺术家包括 Patch,Line2D,Collection,甚至文
本。每个艺术家的路径效果都可以通过 set_path_effects方法
(set_path_effects)控制,它需要一个 AbstractPathEffect的可迭代实
例。
最简单的路径效果是普通效果,它简单地绘制艺术家,并没有任何效果:
importmatplotlib.pyplotasplt
importmatplotlib.patheffectsaspath_effects
fig=plt.figure(figsize=(5,1.5))
text=fig.text(0.5,0.5,'Hellopatheffectsworld!\nThisisth
enormal'
'patheffect.\nPrettydull,huh?',
ha='center',va='center',size=20)
text.set_path_effects([path_effects.Normal()])
plt.show()
添加阴影
比正常效果更有趣的路径效果是阴影,我们可以应用于任何基于路径的艺术家。
SimplePatchShadow和SimpleLineShadow类通过在基本艺术家下面绘制填充
补丁或线条补丁来实现它:
路径效果指南
106

importmatplotlib.pyplotasplt
importmatplotlib.patheffectsaspath_effects
text=plt.text(0.5,0.5,'Hellopatheffectsworld!',
path_effects=[path_effects.withSimplePatchShadow
()])
plt.plot([0,3,2,5],linewidth=5,color='blue',
path_effects=[path_effects.SimpleLineShadow(),
path_effects.Normal()])
plt.show()
请注意本示例中设置路径效果的两种方法。第一个使用 with*类,来包含“正
常”效果之后的所需功能,而后者明确定义要绘制的两个路径效果。
让艺术家脱颖而出
使艺术家在视觉上脱颖而出的一个好方法是,在实际艺术家下面以粗体颜色绘制轮
廓。Stroke路径效果使其相对简单:
路径效果指南
107

importmatplotlib.pyplotasplt
importmatplotlib.patheffectsaspath_effects
fig=plt.figure(figsize=(7,1))
text=fig.text(0.5,0.5,'Thistextstandsoutbecauseof\n'
'itsblackborder.',color='white',
ha='center',va='center',size=30)
text.set_path_effects([path_effects.Stroke(linewidth=3,foregrou
nd='black'),
path_effects.Normal()])
plt.show()
重要的是注意,这种效果能够工作,因为我们已经绘制两次文本路径:一次使用粗
黑线,然后另一次使用原始文本路径在上面绘制。
您可能已经注意到, Stroke、SimplePatchShadow和SimpleLineShadow的
关键字不是通常的 Artist关键字(例如 facecolor和edgecolor等)。这是
因为使用这些路径效果,我们操作了matplotlib的较低层。实际上,接受的关键字
是用于 matplotlib.backend_bases.GraphicsContextBase实例的关键字,它
们为易于创建新的后端而设计,而不是用于其用户界面。
对路径效果艺术家的更大控制
如前所述,一些路径效果的操作级别低于大多数用户操作,这意味着设置关键字
(如 facecolor和edgecolor)会导致 AttributeError。幸运的是,有一个
通用的 PathPatchEffect路径效果,它创建一个具有原始路径
的PathPatch类。此效果的关键字与 PathPatch相同:
路径效果指南
108

importmatplotlib.pyplotasplt
importmatplotlib.patheffectsaspath_effects
fig=plt.figure(figsize=(8,1))
t=fig.text(0.02,0.5,'Hatchshadow',fontsize=75,weight=1000
,va='center')
t.set_path_effects([path_effects.PathPatchEffect(offset=(4,-4),
hatch='xxxx',
facecolor='gra
y'),
path_effects.PathPatchEffect(edgecolor='whit
e',linewidth=1.1,
facecolor='blac
k')])
plt.show()
路径效果指南
109

文本处理
处理文本
110

引言
原文:Textintroduction
译者:飞龙
协议:CCBY-NC-SA4.0
matplotlib具有优秀的文本支持,包括数学表达式,光栅和向量输出的truetype支
持,任意旋转的换行分隔文本和unicode支持。因为我们直接在输出文档中嵌入字
体,例如postscript或PDF,你在屏幕上看到的也是你在打印件中得到的。
freetype2可产生非常漂亮,抗锯齿的字体,即使在小光栅尺寸下看起来也不错。
matplotlib拥有自己的 matplotlib.font_manager,感谢PaulBarrett,他实现
了一个跨平台,符合W3C标准的字体查找算法。
你可以完全控制每个文本属性(字体大小,字体重量,文本位置和颜色等),并
在rc文件中设置合理的默认值。并且对于那些对数学或科学图像感兴趣的人,
matplotlib实现了大量的TeX数学符号和命令,来支持你图中任何地方放置数学表
达式。
引言
111

基本的文本命令
原文:Basictextcommands
译者:飞龙
协议:CCBY-NC-SA4.0
text
在Axes的任意位置添加文本。
命令式: matplotlib.pyplot.text,面向对
象: matplotlib.axes.Axes.text。
xlabel
向x轴添加轴标签。
命令式: matplotlib.pyplot.xlabel,面向对
象: matplotlib.axes.Axes.set_xlabel。
ylabel
向y轴添加轴标签。
命令式: matplotlib.pyplot.ylabel,面向对
象: matplotlib.axes.Axes.set_ylabel。
title
向Axes添加标题。
命令式: matplotlib.pyplot.title,面向对
象: matplotlib.axes.Axes.set_title。
figtext
向Figure的任意位置添加文本。
基本的文本命令
112

命令式: matplotlib.pyplot.figtext,面向对
象: matplotlib.figure.Figure.text。
suptitle
向Figure添加标题。
命令式: matplotlib.pyplot.suptitle,面向对
象: matplotlib.figure.Figure.suptitle。
annotate
向Axes添加标注,带有可选的箭头。
命令式: matplotlib.pyplot.annotate,面向对
象: matplotlib.axes.Axes.annotate。
所有这些函数创建并返回一个 matplotlib.text.Text()实例,它可以配置各种
字体和其他属性。下面的示例在实战中展示所有这些命令。
基本的文本命令
113

#-*-coding:utf-8-*-
importmatplotlib.pyplotasplt
fig=plt.figure()
fig.suptitle('boldfiguresuptitle',fontsize=14,fontweight='bo
ld')
ax=fig.add_subplot(111)
fig.subplots_adjust(top=0.85)
ax.set_title('axestitle')
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
ax.text(3,8,'boxeditalicstextindatacoords',style='italic'
,
bbox={'facecolor':'red','alpha':0.5,'pad':10})
ax.text(2,6,r'anequation:$E=mc^2$',fontsize=15)
ax.text(3,2,u'unicode:Institutf\374rFestk\366rperphysik')
ax.text(0.95,0.01,'coloredtextinaxescoords',
verticalalignment='bottom',horizontalalignment='right',
transform=ax.transAxes,
color='green',fontsize=15)
ax.plot([2],[1],'o')
ax.annotate('annotate',xy=(2,1),xytext=(3,4),
arrowprops=dict(facecolor='black',shrink=0.05))
ax.axis([0,10,0,10])
plt.show()
基本的文本命令
114

基本的文本命令
115

文本属性及布局
原文:Textpropertiesandlayout
译者:飞龙
协议:CCBY-NC-SA4.0
matplotlib.text.Text实例有各种属性,可以通过关键字参数配置文本命令
(例如, title(),xlabel()和text())。
属性 值类型
alpha 浮点
backgroundcolor 任何matplotlib颜色
bbox rectanglepropdictpluskey'pad'whichisapadinpoints
clip_box matplotlib.transform.Bbox实例
clip_on [True/False]
clip_path Path,Transform或Patch实例
color 任何matplotlib颜色
family ['serif'/'sans-serif'/'cursive'/'fantasy'/'monospace']
fontproperties matplotlib.font_manager.FontProperties实例
horizontalalignment
orha ['center'/'right'/'left']
label 任何字符串
linespacing 浮点
multialignment ['left'/'right'/'center']
nameorfontname 字符串,例如['Sans'/'Courier'/'Helvetica'...]
picker [ None/浮点/布尔值/可调用对象]`
position (x,y)
rotation [角度制的角度/'vertical'/'horizontal'
sizeorfontsize [点的尺寸
styleorfontstyle ['normal'/'italic'/'oblique']
文本属性及布局
116

text 字符串或任何可使用 '%s'打印的东西
transform matplotlib.transform实例
variant ['normal'/'small-caps']
verticalalignmentor
va ['center'/'top'/'bottom'/'baseline']
visible [True/False]
weightor
fontweight ['normal'/'bold'/'heavy'/'light'/'ultrabold'/'ultralight']
x浮点
y浮点
zorder 任意数值
你可以使用对齐参
数horizontalalignment,verticalalignment和multialignment来布置
文本。horizontalalignment控制文本的 x位置参数表示文本边界框的左边,
中间或右边。verticalalignment控制文本的 y位置参数表示文本边界框的底
部,中心或顶部。multialignment,仅对于换行符分隔的字符串,控制不同的
行是左,中还是右对齐。这里是一个使用 text()命令显示各种对齐方式的例
子。在整个代码中使用 transform=ax.transAxes,表示坐标相对于轴边界框
给出,其中 0,0是轴的左下角, 1,1是右上角。
importmatplotlib.pyplotasplt
importmatplotlib.patchesaspatches
#buildarectangleinaxescoords
left,width=.25,.5
bottom,height=.25,.5
right=left+width
top=bottom+height
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
#axescoordinatesare0,0isbottomleftand1,1isupperright
p=patches.Rectangle(
(left,bottom),width,height,
fill=False,transform=ax.transAxes,clip_on=False
)
ax.add_patch(p)
ax.text(left,bottom,'lefttop',
horizontalalignment='left',
verticalalignment='top',
文本属性及布局
117

transform=ax.transAxes)
ax.text(left,bottom,'leftbottom',
horizontalalignment='left',
verticalalignment='bottom',
transform=ax.transAxes)
ax.text(right,top,'rightbottom',
horizontalalignment='right',
verticalalignment='bottom',
transform=ax.transAxes)
ax.text(right,top,'righttop',
horizontalalignment='right',
verticalalignment='top',
transform=ax.transAxes)
ax.text(right,bottom,'centertop',
horizontalalignment='center',
verticalalignment='top',
transform=ax.transAxes)
ax.text(left,0.5*(bottom+top),'rightcenter',
horizontalalignment='right',
verticalalignment='center',
rotation='vertical',
transform=ax.transAxes)
ax.text(left,0.5*(bottom+top),'leftcenter',
horizontalalignment='left',
verticalalignment='center',
rotation='vertical',
transform=ax.transAxes)
ax.text(0.5*(left+right),0.5*(bottom+top),'middle',
horizontalalignment='center',
verticalalignment='center',
fontsize=20,color='red',
transform=ax.transAxes)
ax.text(right,0.5*(bottom+top),'centered',
horizontalalignment='center',
verticalalignment='center',
rotation='vertical',
transform=ax.transAxes)
ax.text(left,top,'rotated\nwithnewlines',
horizontalalignment='center',
verticalalignment='center',
rotation=45,
transform=ax.transAxes)
ax.set_axis_off()
文本属性及布局
118

plt.show()
文本属性及布局
119

默认字体
原文:Textpropertiesandlayout
译者:飞龙
协议:CCBY-NC-SA4.0
基本的默认字体由一系列 rcParams参数控制:
rcParam 用法
'font.family'
字体名称
或{'cursive','fantasy','monospace','sans','sansserif','sans-serif','serif'}
列表
'font.style' 默认字体,例如 'normal','italic'
'font.variant' 默认变体,例如 'normal','small-caps'(未测试)
'font.stretch' 默认拉伸 'normal','condensed'(未完成)
'font.weight' 字体粗细,可为整数或字符串
'font.size' 默认字体大小(以磅为单位)。相对字体大小( 'large'
字体系列别名
({'cursive','fantasy','monospace','sans','sansserif','sans-serif','serif'}
)和实际字体名称之间的映射由以下 rcParams控制:
系列别名 映射的 rcParam
'serif' 'font.serif'
'monospace' 'font.monospace'
'fantasy' 'font.fantasy'
'cursive' 'font.cursive'
{'sans','sansserif','sans-serif'} 'font.sans-serif'
它是字体名称的列表。
非拉丁字形文本
从v2.0开始,默认字体包含许多西方字母的字形,但仍然没有覆盖mpl用户可能
需要的所有字形。例如,DejaVu没有覆盖中文,韩语或日语。
默认字体
120

要将默认字体设置为支持所需代码点的字体,请将字体名称添加
到font.family或所需的别名列表前面。
matplotlib.rcParams['font.sans-serif']=['SourceHanSansTW',
'sans-serif']
或在 .matplotlibrc文件中设置:
font.sans-serif:SourceHanSansTW,Ariel,sans-serif
要控制每个艺术家使用的字体,使用上面记录
的'name','fontname'或'fontproperties'关键字参数。
在linux上, fc-list是用于发现字体名称的实用工具;例如
$fc-list:lang=zhfamily
NototoSansMonoCJKTC,NotoSansMonoCJKTCBold
NotoSansCJKTC,NotoSansCJKTCMedium
NotoSansCJKTC,NotoSansCJKTCDemiLight
NotoSansCJKKR,NotoSansCJKKRBlack
NotoSansCJKTC,NotoSansCJKTCBlack
NotoSansMonoCJKTC,NotoSansMonoCJKTCRegular
NotoSansCJKSC,NotoSansCJKSCLight
列出了所有支持中文的字体。
默认字体
121

标注
原文:Annotation
译者:飞龙
协议:CCBY-NC-SA4.0
基本标注
使用 text()会将文本放置在轴域的任意位置。文本的一个常见用例是标注绘图
的某些特征,而 annotate()方法提供辅助函数,使标注变得容易。在标注中,
有两个要考虑的点:由参数 xy表示的标注位置和 xytext的文本位置。这两个
参数都是 (x,y)元组。
importnumpyasnp
importmatplotlib.pyplotasplt
fig=plt.figure()
ax=fig.add_subplot(111)
t=np.arange(0.0,5.0,0.01)
s=np.cos(2*np.pi*t)
line,=ax.plot(t,s,lw=2)
ax.annotate('localmax',xy=(2,1),xytext=(3,1.5),
arrowprops=dict(facecolor='black',shrink=0.05),
)
ax.set_ylim(-2,2)
plt.show()
源代码
标注
122

在该示例中, xy(箭头尖端)和 xytext位置(文本位置)都以数据坐标为单
位。有多种可以选择的其他坐标系-你可以使用 xycoords和textcoords以及
下列字符串之一(默认为 data)指定 xy和xytext的坐标系。
|参数|坐标系|| 'figurepoints'|距离图形左下角的点数量||
'figurepixels'|距离图形左下角的像素数量|| 'figurefraction'|0,0
是图形左下角,1,1是右上角|| 'axespoints'|距离轴域左下角的点数量||
'axespixels'|距离轴域左下角的像素数量|| 'axesfraction'|0,0是轴
域左下角,1,1是右上角|| 'data'|使用轴域数据坐标系|
例如将文本以轴域小数坐标系来放置,我们可以:
ax.annotate('localmax',xy=(3,1),xycoords='data',
xytext=(0.8,0.95),textcoords='axesfraction',
arrowprops=dict(facecolor='black',shrink=0.05),
horizontalalignment='right',verticalalignment='top'
,
)
对于物理坐标系(点或像素),原点是图形或轴的左下角。
或者,你可以通过在可选关键字参数 arrowprops中提供箭头属性字典来绘制从
文本到注释点的箭头。
标注
123

arrowprops键 描述
width 箭头宽度,以点为单位
frac 箭头头部所占据的比例
headwidth 箭头的底部的宽度,以点为单位
shrink 移动提示,并使其离注释点和文本一些距离
**kwargs matplotlib.patches.Polygon的任何键,例
如facecolor
在下面的示例中, xy点是原始坐标( xycoords默认为 'data')。对于极坐
标轴,它在 (theta,radius)空间中。此示例中的文本放置在图形小数坐标系
中。matplotlib.text.Text关键字 args,例
如horizontalalignment,verticalalignment和fontsize,
从annotate传给 Text实例。
源代码
注释(包括花式箭头)的所有高上大的内容的更多信息,请参阅高级标注
和pylab_examples示例代码: annotation_demo.py。
不要继续,除非你已经阅读了基本标注,text()和annotate()。
高级标注
标注
124

使用框和文本来标注
让我们以一个简单的例子来开始。
源代码
在pyplot模块(或 Axes类的 text方法)中的 text()函数接受 bbox关键
字参数,并且在提供时,在文本周围绘制一个框。
与文本相关联的补丁对象可以通过以下方式访问:
bb=t.get_bbox_patch()
返回值是 FancyBboxPatch的一个实例,并且补丁属性
(如 facecolor,edgewidth等)可以像平常一样访问和修改。为了更改框的
形状,请使用 set_boxstyle方法。
bb.set_boxstyle("rarrow",pad=0.6)
该参数是框样式的名称与其作为关键字参数的属性。目前,实现了以下框样式。
标注
125

类 名称 属性
Circle circle pad=0.3
DArrow darrow pad=0.3
LArrow larrow pad=0.3
RArrow rarrow pad=0.3
Round round pad=0.3,rounding_size=None
Round4 round4 pad=0.3,rounding_size=None
Roundtooth roundtooth pad=0.3,tooth_size=None
Sawtooth sawtooth pad=0.3,tooth_size=None
Square square pad=0.3
源代码
标注
126

注意,属性参数可以在样式名称中用逗号分隔(在初始化文本实例时,此形式可以
用作 bbox参数的 boxstyle的值)。
bb.set_boxstyle("rarrow,pad=0.6")
使用箭头来标注
pyplot模块(或 Axes类的 annotate方法)中的 annotate()函数用于绘制
连接图上两点的箭头。
标注
127

ax.annotate("Annotation",
xy=(x1,y1),xycoords='data',
xytext=(x2,y2),textcoords='offsetpoints',
)
这会使用 textcoords中提供的, xytext处的文本标注提供坐标
(xycoords)中的 xy处的点。通常,数据坐标中规定了标注点,偏移点中规
定了标注文本。请参阅 annotate()了解可用的坐标系。
连接两个点( xy和xytext)的箭头可以通过指定 arrowprops参数可选地绘
制。为了仅绘制箭头,请使用空字符串作为第一个参数。
ax.annotate("",
xy=(0.2,0.2),xycoords='data',
xytext=(0.8,0.8),textcoords='data',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3"),
)
源代码
箭头的绘制需要几个步骤。
创建两个点之间的连接路径。这由 connectionstyle键值控制。
如果提供了补丁对象( patchA和patchB),则会剪切路径以避开该补
丁。
路径进一步由提供的像素总量来缩小( shirnkA&shrinkB)
路径转换为箭头补丁,由 arrowstyle键值控制。
源代码
标注
128

两个点之间的连接路径的创建由 connectionstyle键控制,并且可用以下样式。
名称 属性
angle angleA=90,angleB=0,rad=0.0
angle3 angleA=90,angleB=0
arc angleA=0,angleB=0,armA=None,armB=None,rad=0.0
arc3 rad=0.0
bar armA=0.0,armB=0.0,fraction=0.3,angle=None
注意, angle3和arc3中的 3意味着所得到的路径是二次样条段(三个控制
点)。如下面将讨论的,当连接路径是二次样条时,可以使用一些箭头样式选项。
每个连接样式的行为在下面的示例中(有限地)演示。(警告:条形样式的行为当
前未定义好,将来可能会更改)。
源代码
标注
129

然后根据给定的箭头样式将连接路径(在剪切和收缩之后)变换为箭头补丁。
名称 属性
-None
-> head_length=0.4,head_width=0.2
-[ widthB=1.0,lengthB=0.2,angleB=None
|-| widthA=1.0,widthB=1.0
-|> head_length=0.4,head_width=0.2
<- head_length=0.4,head_width=0.2
<-> head_length=0.4,head_width=0.2
<|- head_length=0.4,head_width=0.2
< -|> head_length=0.4,head_width=0.2
fancy head_length=0.4,head_width=0.4,tail_width=0.4
simple head_length=0.5,head_width=0.5,tail_width=0.2
wedge tail_width=0.3,shrink_factor=0.5
源代码
标注
130

frommpl_toolkits.axes_grid.anchored_artistsimportAnchoredText
at=AnchoredText("Figure1a",
prop=dict(size=8),frameon=True,
loc=2,
)
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
源代码
loc关键字与 legend命令中含义相同。
一个简单的应用是当艺术家(或艺术家的集合)的像素大小在创建时已知。例如,
如果要绘制一个固定大小为20像素×20像素(半径为10像素)的圆,则可以使
用AnchoredDrawingArea。实例使用绘图区域的大小创建(以像素为单位)。
用户可以在绘图区任意添加艺术家。注意,添加到绘图区域的艺术家的范围与绘制
区域本身的位置无关,只和初始大小有关。
frommpl_toolkits.axes_grid.anchored_artistsimportAnchoredDraw
ingArea
ada=AnchoredDrawingArea(20,20,0,0,
loc=1,pad=0.,frameon=False)
p1=Circle((10,10),10)
ada.drawing_area.add_artist(p1)
p2=Circle((30,10),5,fc="r")
ada.drawing_area.add_artist(p2)
添加到绘图区域的艺术家不应该具有变换集(它们将被重写),并且那些艺术家的
尺寸被解释为像素坐标,即,上述示例中的圆的半径分别是10像素和5像素。
源代码
标注
133

有时,你想让你的艺术家按数据坐标(或其他坐标,而不是画布像素)缩放。你可
以使用 AnchoredAuxTransformBox类。这类似于 AnchoredDrawingArea,除
了艺术家的范围在绘制时由指定的变换确定。
frommpl_toolkits.axes_grid.anchored_artistsimportAnchoredAuxT
ransformBox
box=AnchoredAuxTransformBox(ax.transData,loc=2)
el=Ellipse((0,0),width=0.1,height=0.4,angle=30)#indatac
oordinates!
box.drawing_area.add_artist(el)
上述示例中的椭圆具有在数据坐标中对应于0.1和0.4的宽度和高度,并且当轴域
的视图限制改变时将自动缩放。
源代码
标注
134

如图例所示,可以设置 bbox_to_anchor参数。使用 HPacker和VPacker,
你可以像图例中一样排列艺术家(事实上,这是图例的创建方式)。
源代码
请注意,与图例不同,默认情况下, bbox_transform设置
为IdentityTransform。
使用复杂坐标来标注
matplotlib中的标注支持标注文本中描述的几种类型的坐标。对于想要更多控制的
高级用户,它支持几个其他选项。
1. Transform实例,例如:
ax.annotate("Test",xy=(0.5,0.5),xycoords=ax.transAxes)
相当于:
ax.annotate("Test",xy=(0.5,0.5),xycoords="axesfraction")
使用它,你可以在其他轴域内标注一个点:
ax1,ax2=subplot(121),subplot(122)
ax2.annotate("Test",xy=(0.5,0.5),xycoords=ax1.transData,
xytext=(0.5,0.5),textcoords=ax2.transData,
arrowprops=dict(arrowstyle="->"))
2. Artist实例。 xy值(或 xytext)被解释为艺术家
的bbox(get_window_extent的返回值)的小数坐标。
标注
135

an1=ax.annotate("Test1",xy=(0.5,0.5),xycoords="data",
va="center",ha="center",
bbox=dict(boxstyle="round",fc="w"))
an2=ax.annotate("Test2",xy=(1,0.5),xycoords=an1,#(1,
0.5)ofthean1'sbbox
xytext=(30,0),textcoords="offsetpoints",
va="center",ha="left",
bbox=dict(boxstyle="round",fc="w"),
arrowprops=dict(arrowstyle="->"))
源代码
请注意,你的责任是在绘制 an2之前确定坐标艺术家(上例中的 an1)的范
围。在大多数情况下,这意味着 an2需要晚于 an1。
3. 一个返回 BboxBase或Transform的实例的可调用对象。如果返回一个变
换,它与1相同,如果返回 bbox,它与2相同。可调用对象应该接
受renderer实例的单个参数。例如,以下两个命令产生相同的结果:
an2=ax.annotate("Test2",xy=(1,0.5),xycoords=an1,
xytext=(30,0),textcoords="offsetpoints")
an2=ax.annotate("Test2",xy=(1,0.5),xycoords=an1.get_wi
ndow_extent,
xytext=(30,0),textcoords="offsetpoints")
4. 指定二元坐标的元组。第一项用于 x坐标,第二项用于 y坐标。例如,
annotate("Test",xy=(0.5,1),xycoords=("data","axesfracti
on"))
0.5的单位是数据坐标,1的单位是归一化轴域坐标。你可以像使用元组一样
使用艺术家或变换。例如,
标注
136

importmatplotlib.pyplotasplt
plt.figure(figsize=(3,2))
ax=plt.axes([0.1,0.1,0.8,0.7])
an1=ax.annotate("Test1",xy=(0.5,0.5),xycoords="data",
va="center",ha="center",
bbox=dict(boxstyle="round",fc="w"))
an2=ax.annotate("Test2",xy=(0.5,1.),xycoords=an1,
xytext=(0.5,1.1),textcoords=(an1,"axesf
raction"),
va="bottom",ha="center",
bbox=dict(boxstyle="round",fc="w"),
arrowprops=dict(arrowstyle="->"))
plt.show()
源代码
5. 有时,您希望您的注释带有一些“偏移点”,不是距离注释点,而是距离某些其
他点。OffsetFrom是这种情况下的辅助类。
标注
137

importmatplotlib.pyplotasplt
plt.figure(figsize=(3,2))
ax=plt.axes([0.1,0.1,0.8,0.7])
an1=ax.annotate("Test1",xy=(0.5,0.5),xycoords="data",
va="center",ha="center",
bbox=dict(boxstyle="round",fc="w"))
frommatplotlib.textimportOffsetFrom
offset_from=OffsetFrom(an1,(0.5,0))
an2=ax.annotate("Test2",xy=(0.1,0.1),xycoords="data",
xytext=(0,-10),textcoords=offset_from,
#xytextisoffsetpointsfrom"xy=(0.5,0
),xycoords=an1"
va="top",ha="center",
bbox=dict(boxstyle="round",fc="w"),
arrowprops=dict(arrowstyle="->"))
plt.show()
你可以参考这个链
接: pylab_examplesexamplecode:annotation_demo3.py.。
使用 ConnectorPatch
ConnectorPatch类似于没有文本的标注。虽然在大多数情况下建议使用标注函
数,但是当您想在不同的轴上连接点时, ConnectorPatch很有用。
frommatplotlib.patchesimportConnectionPatch
xy=(0.2,0.2)
con=ConnectionPatch(xyA=xy,xyB=xy,coordsA="data",coordsB="d
ata",
axesA=ax1,axesB=ax2)
ax2.add_artist(con)
上述代码连接了 ax1中数据坐标的 xy点,与 ax2中数据坐标的 xy点。这是
个简单的例子。
标注
138

定义自定义盒样式
你可以使用自定义盒样式, boxstyle的值可以为如下形式的可调用对象:
def__call__(self,x0,y0,width,height,mutation_size,
aspect_ratio=1.):
"""
Giventhelocationandsizeofthebox,returnthepathof
theboxaroundit.
-*x0*,*y0*,*width*,*height*:locationandsizeofthe
box
-*mutation_size*:areferencescaleforthemutation.
-*aspect_ratio*:aspect-ratioforthemutation.
"""
path=...
returnpath
这里是个复杂的例子:
源代码
标注
140

但是,推荐你从 matplotlib.patches.BoxStyle._Base派生,像这样:
frommatplotlib.pathimportPath
frommatplotlib.patchesimportBoxStyle
importmatplotlib.pyplotasplt
#wemayderivefrommatplotlib.patches.BoxStyle._Baseclass.
#Youneedtooverridetransmutemethodinthiscase.
classMyStyle(BoxStyle._Base):
"""
Asimplebox.
"""
def__init__(self,pad=0.3):
"""
Theargumentsneedtobefloatingnumbersandneedtoha
ve
defaultvalues.
*pad*
amountofpadding
"""
self.pad=pad
super(MyStyle,self).__init__()
deftransmute(self,x0,y0,width,height,mutation_size):
"""
Giventhelocationandsizeofthebox,returnthepath
of
theboxaroundit.
-*x0*,*y0*,*width*,*height*:locationandsizeof
thebox
-*mutation_size*:areferencescaleforthemutation.
标注
141

Often,the*mutation_size*isthefontsizeofthetext.
Youdon'tneedtoworryabouttherotationasitis
automaticallytakencareof.
"""
#padding
pad=mutation_size*self.pad
#widthandheightwithpaddingadded.
width,height=width+2.*pad,\
height+2.*pad,
#boundaryofthepaddedbox
x0,y0=x0-pad,y0-pad,
x1,y1=x0+width,y0+height
cp=[(x0,y0),
(x1,y0),(x1,y1),(x0,y1),
(x0-pad,(y0+y1)/2.),(x0,y0),
(x0,y0)]
com=[Path.MOVETO,
Path.LINETO,Path.LINETO,Path.LINETO,
Path.LINETO,Path.LINETO,
Path.CLOSEPOLY]
path=Path(cp,com)
returnpath
#registerthecustomstyle
BoxStyle._style_list["angled"]=MyStyle
plt.figure(1,figsize=(3,3))
ax=plt.subplot(111)
ax.text(0.5,0.5,"Test",size=30,va="center",ha="center",rot
ation=30,
bbox=dict(boxstyle="angled,pad=0.5",alpha=0.2))
delBoxStyle._style_list["angled"]
plt.show()
源代码
标注
142

与之类似,您可以定义一个自定义的 ConnectionStyle和一个自定义
的ArrowStyle。请参阅 lib/matplotlib/patches.py的源代码,并查看每个
样式类是如何定义的。
标注
143

编写数学表达式
原文:Writingmathematicalexpressions
译者:飞龙
协议:CCBY-NC-SA4.0
你可以在任何matplotlib文本字符串中使用子TeX标记,将它放在一对美元符号
($)内。
注意,你不需要安装TeX,因为matplotlib提供了自己的TeX表达式解析器,布局
引擎和字体。布局引擎是DonaldKnuth的TeX中的布局算法的一种相当直接的适
配版,所以质量是相当不错的(matplotlib还为那些想要调用TeX生成文本的人提
供一个 usetex选项(参见使用LaTeX渲染文本)。
任何文本元素都可以使用数学文本。你应该使用原始字符串(在引号前面加一
个'r'),并用美元符号( $)包围数学文本,如TeX。常规文本和数学文本
可以在同一个字符串内交错。Mathtext可以使用ComputerModern字体(来自
(La)TeX),STIX字体(为与Times混合使用而设计)或你提供的Unicode字
体。可以使用自定义变量 mathtext.fontset选择mathtext字体(请参阅自定义
matplotlib)
注意
在Python的『narrow』构建中,如果使用STIX字体,你还应该
将ps.fonttype和pdf.fonttype设置为3(默认值),而不是42。否则
一些字符将不可见。
下面是个简单的例子:
#plaintext
plt.title('alpha>beta')
生成 alpha>beta。
但是这个:
#mathtext
plt.title(r'$\alpha>\beta$')
生成。
编写数学表达式
144

注意
Mathtext应该放在一对美元符号( $)之间。为了易于显示货币值,例
如$100.00,如果整个字符串中存在单个美元符号,则它将被逐字显示为美
元符号。这是常规TeX的一个小改变,其中非数学文本中的美元符号必须被
转义( '$')。
注意
虽然一对美元符号( $)内的语法是TeX风格的,但是外面的文本不是。特
别是,字符:
#$%&~_^\{}\(\)\[\]
在TeX中的数学模式之外有特殊的意义。因此,根
据rcParamtext.usetex标志这些字符的表现有所不同。更多信息请参
阅usetex教程。
下标和上标
为了制作下标和上标,使用 _或者 ^符号:
r'$\alpha_i>\beta_i$'
一些符号会自动将它们的下标或上标放在操作符的底部或顶部,例如,为了编写0
到无穷的 的和,你可以:
r'$\sum_{i=0}^\inftyx_i$'
分数、二项式和堆叠数
可以使用 \frac{}{},\binomial{}{}和\stackrel{}{}命令分别创建分
数,二项式和堆叠数字:
r'$\frac{3}{4}\binom{3}{4}\stackrel{3}{4}$'
产生
编写数学表达式
145

分数可以任意嵌套:
r'$\frac{5-\frac{1}{x}}{4}$'
产生
请注意,在分数周围放置圆括号和花括号需要特别注意。这种明显的方式会产生太
小的括号:
r'$(\frac{5-\frac{1}{x}}{4})$'
解决方案是在括号前面加上 \left和\right以通知解析器这些括号包含整个对
象:
r'$\left(\frac{5-\frac{1}{x}}{4}\right)$'
根式
根式可以有 \sqrt[]{}产生,例如:
r'$\sqrt{2}$'
方括号内可以(可选地)设置任何底数。请注意,底数必须是一个简单的表达式,
并且不能包含布局命令,如分数或上下标:
r'$\sqrt[3]{x}$'
编写数学表达式
146

字体
用于数学符号的默认字体是斜体。
注意
此默认值可以使用 mathtext.defaultrcParam更改。这是非常有用的,
例如,通过将其设置为 regular,使用与常规非数学文本相同的字体作为数
学文本。
为了修改字体,例如,以罗马字体编写 sin,使用字体命令来闭合文本:
r'$s(t)=\mathcal{A}\mathrm{sin}(2\omegat)$'
这里 s和t是斜体(默认)的变量, sin是罗马字体,振幅 A是书法字体。
注意在上面的例子中, A和sin之间的间距被挤压。你可以使用间距命令在它
们之间添加一些空格:
s(t)=\mathcal{A}\/\sin(2\omegat)
所有字体的可用选项为:
命令 结果
\mathrm{Roman}
\mathit{Italic}
\mathtt{Typewriter}
\mathcal{CALLIGRAPHY}
使用STIX字体时,你也可以选择:
编写数学表达式
147

命令 结果
\mathbb{blackboard}
\mathrm{\mathbb{blackboard}}
\mathfrak{Fraktur}
\mathsf{sansserif}
\mathrm{\mathsf{sansserif}}
\mathcircled{circled}
还有三个全局『字体集』可供选择,它们使用 matplotlibrc中
的mathtext.fontset参数进行选择。
cm:ComputerModern(TeX)
stix:STIX(为和Times混合使用而设计)
stixsans:STIXsans-serif
此外,你可以使用 \mathdefault{...}或其别名 \mathregular{...}来使用用
于mathtext之外的常规文本的字体。这种方法有一些限制,最明显的是,可以使
用很少的符号,但可用于将数学表达式与图中的其他文本混合。
自定义字体
mathtext还提供了一种对数学公式使用自定义字体的方法。这种方法使用起来相当
棘手,应该看做为有耐心的用户准备的试验特性。通过
将rcParammathtext.fontset设置为 custom,你可以设置以下参数,这些参
数控制用于特定数学字符集的字体文件。
编写数学表达式
148

参数 相当于
mathtext.it \mathit{}默认斜体
mathtext.rm \mathrm{}罗马字体(upright)
mathtext.tt \mathtt{}打字机(monospace)
mathtext.bf \mathbf{}粗体
mathtext.cal \mathcal{}书法
mathtext.sf \mathsf{}sans-serif
每个参数应该设置为 fontconfig字体描述符(在尚未编写的字体章节中定
义)。
所使用的字体应该具有Unicode映射,以便找到任何非拉丁字符,例如希腊语。
如果要使用未包含在自定义字体中的数学符号,可以
将rcParammathtext.fallback_to_cm设置为 True,这将导致自定义字体中
找不到特定字符时,数学文本系统使用默认的ComputerModern字体中的字符。
请注意,Unicode中规定的数学字形随时间而演进,许多字体的字形对于mathtext
可能不在正确位置。
重音符号
重音命令可以位于任何符号之前,在其上添加重音。他们中的一些些拥有较长和较
短的形式。
命令 结果
\acutea或\'a
\bara
\brevea
\ddota或\"a
\dota或\.a
\gravea或\a`
\hata或\^a
\tildea或\~a
\veca
\overline{abc}
另外有两个特殊的重音符号,可以自动调整为符号的宽度:
编写数学表达式
149

命令 结果
\widehat{xyz}
\widetilde{xyz}
当把重音放在小写的 i和j上时应该小心。注意下面的 \imath用来避免 i上
额外的点:
r"$\hati\\\hat\imath$"
符号
你也可以使用更大量的TeX符号,比
如\infty,\leftarrow,\sum,\int。
小写希腊字
母
\alpha \beta \chi \delta \digamma
\epsilon \eta \gamma \iota \kappa
\lambda \mu \nu \omega \phi
\pi \psi \rho \sigma \tau
\theta \upsilon \varepsilon \varkappa \varphi
\varpi \varrho \varsigma \vartheta \xi
\zeta
编写数学表达式
150

大写希腊字
母
\Delta \Gamma \Lambda \Omega \Phi \Pi
\Psi \Sigma \Theta \Upsilon \Xi \mho
\nabla
希伯来文
\aleph \beth \daleth \gimel
分隔符
/ [ \Downarrow \Uparrow \Vert
\downarrow \langle \lceil \lfloor \llcorner
\rangle \rceil \rfloor \ulcorner \uparrow
\vert \{ `\ `\}
大型符号
\bigcap \bigcup \bigodot \bigoplus \bigotimes
\biguplus \bigvee \bigwedge \coprod \int
\oint \prod \sum
编写数学表达式
151

标准函数名称
\Pr \arccos \arcsin \arctan
\arg \cos \cosh \cot
\coth \csc \deg \det
\dim \exp \gcd \hom
\inf \ker \lg \lim
\liminf \limsup \ln \log
\max \min \sec \sin
\sinh \sup \tan \tanh
二元运算符和关系符
号
\Bumpeq \Cap \Cup
\Doteq \Join \Subset
\Supset \Vdash \Vvdash
\approx \approxeq \ast
\asymp \backepsilon \backsim
\backsimeq \barwedge \because
\between \bigcirc \bigtriangledown
\bigtriangleup \blacktriangleleft \blacktriangleright
\bot \bowtie \boxdot
\boxminus \boxplus \boxtimes
\bullet \bumpeq \cap
\cdot \circ \circeq
\coloneq \cong \cup
\curlyeqprec \curlyeqsucc \curlyvee
\curlywedge \dag \dashv
编写数学表达式
152

\ddag \diamond \div
\divideontimes \doteq \doteqdot
\dotplus \doublebarwedge \eqcirc
\eqcolon \eqsim \eqslantgtr
\eqslantless \equiv \fallingdotseq
\frown \geq \geqq
\geqslant \gg \ggg
\gnapprox \gneqq \gnsim
\gtrapprox \gtrdot \gtreqless
\gtreqqless \gtrless \gtrsim
\in \intercal \leftthreetimes
\leq \leqq \leqslant
\lessapprox \lessdot \lesseqgtr
\lesseqqgtr \lessgtr \lesssim
\ll \lll \lnapprox
\lneqq \lnsim \ltimes
\mid \models \mp
\nVDash \nVdash \napprox
\ncong \ne \neq
\neq \nequiv \ngeq
\ngtr \ni \nleq
\nless \nmid \notin
\nparallel \nprec \nsim
\nsubset \nsubseteq \nsucc
\nsupset \nsupseteq \ntriangleleft
编写数学表达式
153

\ntrianglelefteq \ntriangleright \ntrianglerighteq
\nvDash \nvdash \odot
\ominus \oplus \oslash
\otimes \parallel \perp
\pitchfork \pm \prec
\precapprox \preccurlyeq \preceq
\precnapprox \precnsim \precsim
\propto \rightthreetimes \risingdotseq
\rtimes \sim \simeq
\slash \smile \sqcap
\sqcup \sqsubset \sqsubset
\sqsubseteq \sqsupset \sqsupset
\sqsupseteq \star \subset
\subseteq \subseteqq \subsetneq
\subsetneqq \succ \succapprox
\succcurlyeq \succeq \succnapprox
\succnsim \succsim \supset
\supseteq \supseteqq \supsetneq
\supsetneqq \therefore \times
\top \triangleleft \trianglelefteq
\triangleq \triangleright \trianglerighteq
\uplus \vDash \varpropto
\vartriangleleft \vartriangleright \vdash
\vee \veebar \wedge
\wr
箭头符号
编写数学表达式
154

\Downarrow \Leftarrow
\Leftrightarrow \Lleftarrow
\Longleftarrow \Longleftrightarrow
\Longrightarrow \Lsh
\Nearrow \Nwarrow
\Rightarrow \Rrightarrow
\Rsh \Searrow
\Swarrow \Uparrow
\Updownarrow \circlearrowleft
\circlearrowright \curvearrowleft
\curvearrowright \dashleftarrow
\dashrightarrow \downarrow
\downdownarrows \downharpoonleft
\downharpoonright \hookleftarrow
\hookrightarrow \leadsto
\leftarrow \leftarrowtail
\leftharpoondown \leftharpoonup
\leftleftarrows \leftrightarrow
\leftrightarrows \leftrightharpoons
\leftrightsquigarrow \leftsquigarrow
\longleftarrow \longleftrightarrow
\longmapsto \longrightarrow
\looparrowleft \looparrowright
\mapsto \multimap
\nLeftarrow \nLeftrightarrow
\nRightarrow \nearrow
\nleftarrow \nleftrightarrow
编写数学表达式
155

\nrightarrow \nwarrow
\rightarrow \rightarrowtail
\rightharpoondown \rightharpoonup
\rightleftarrows \rightleftarrows
\rightleftharpoons \rightleftharpoons
\rightrightarrows \rightrightarrows
\rightsquigarrow \searrow
\swarrow \to
\twoheadleftarrow \twoheadrightarrow
\uparrow \updownarrow
\updownarrow \upharpoonleft
\upharpoonright \upuparrows
编写数学表达式
156

杂项符号
\$ \AA \Finv
\Game \Im \P
\Re \S \angle
\backprime \bigstar \blacksquare
\blacktriangle \blacktriangledown \cdots
\checkmark \circledR \circledS
\clubsuit \complement \copyright
\ddots \diamondsuit \ell
\emptyset \eth \exists
\flat \forall \hbar
\heartsuit \hslash \iiint
\iint \iint \imath
\infty \jmath \ldots
\measuredangle \natural \neg
\nexists \oiiint \partial
\prime \sharp \spadesuit
\sphericalangle \ss \triangledown
\varnothing \vartriangle \vdots
\wp \yen
如果特定符号没有名称(对于STIX字体中的许多较为模糊的符号也是如此),也
可以使用Unicode字符:
ur'$\u23ce$'
示例
下面是个示例,在上下文中展示了许多这些特性。
编写数学表达式
157

importnumpyasnp
importmatplotlib.pyplotasplt
t=np.arange(0.0,2.0,0.01)
s=np.sin(2*np.pi*t)
plt.plot(t,s)
plt.title(r'$\alpha_i>\beta_i$',fontsize=20)
plt.text(1,-0.6,r'$\sum_{i=0}^\inftyx_i$',fontsize=20)
plt.text(0.6,0.6,r'$\mathcal{A}\mathrm{sin}(2\omegat)$',
fontsize=20)
plt.xlabel('time(s)')
plt.ylabel('volts(mV)')
plt.show()
编写数学表达式
158

使用LaTeX渲染文本
原文:TextrenderingWithLaTeX
译者:飞龙
协议:CCBY-NC-SA4.0
Matplotlib可以选择使用LaTeX来管理所有文本布局。此选项可用于以下后端:
Agg
PS
PDF
LaTeX选项通过在 rc设置中设置 text.usetex:True来激活。使用matplotlib
的LaTeX支持的文本处理会慢于matplotlib的非常强大的mathtext,但是更灵活,
因为可以使用不同的LaTeX包(字体包,数学包等)。结果会十分惊人,特别是
当你在图形中使用和主文档相同的字体。
Matplotlib的LaTeX支持需要可用的LaTeX安装版本,dvipng(可能包括在你的
LaTeX安装中)和Ghostscript(建议使用GPLGhostscript8.60或更高版本)。
这些外部依赖的可执行文件必须都位于你的 PATH中。
有几个选项需要提及,可以使用 rc设置更改它们。这里是一
个matplotlibrc示例文件:
font.family:serif
font.serif:Times,Palatino,NewCenturySchoolbook,Bo
okman,ComputerModernRoman
font.sans-serif:Helvetica,AvantGarde,ComputerModernSan
sserif
font.cursive:ZapfChancery
font.monospace:Courier,ComputerModernTypewriter
text.usetex:true
每个系列中的第一个有效字体是要加载的字体。如果未指定字体,则默认使用
ComputerModern字体。所有其他字体是Adobe字体。Times和Palatino每个
都有自己附带的数学字体,而其他Adobe衬线字体使用ComputerModern数学字
体。有关更多详细信息,请参阅PSNFSS文档。
要使用LaTeX并选择Helvetica作为默认字体,但不编辑 matplotlibrc,使
用:
使用LaTeX渲染文本
159

frommatplotlibimportrc
rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})
##forPalatinoandotherseriffontsuse:
#rc('font',**{'family':'serif','serif':['Palatino']})
rc('text',usetex=True)
这里是标准的示例, tex_demo.py:
"""
DemoofTeXrendering.
YoucanuseTeXtorenderallofyourmatplotlibtextiftherc
parametertext.usetexisset.Thisworkscurrentlyontheagga
ndps
backends,andrequiresthatyouhavetexandtheotherdependenc
ies
describedathttp://matplotlib.org/users/usetex.html
properlyinstalledonyoursystem.Thefirsttimeyourunascr
ipt
youwillseealotofoutputfromtexandassociatedtools.The
next
time,therunmaybesilent,asalotoftheinformationiscach
edin
~/.tex.cache
"""
importnumpyasnp
importmatplotlib.pyplotasplt
#Exampledata
t=np.arange(0.0,1.0+0.01,0.01)
s=np.cos(4*np.pi*t)+2
plt.rc('text',usetex=True)
plt.rc('font',family='serif')
plt.plot(t,s)
plt.xlabel(r'\textbf{time}(s)')
plt.ylabel(r'\textit{voltage}(mV)',fontsize=16)
plt.title(r"\TeX\isNumber"
r"$\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}
$!",
fontsize=16,color='gray')
#Makeroomfortheridiculouslylargetitle.
plt.subplots_adjust(top=0.8)
plt.savefig('tex_demo')
plt.show()
使用LaTeX渲染文本
160

要注意数学显示模式( $$e=mc^2$$)是不支持的,但是添加命
令\displaystyle之后会产生相同结果,就像 tex_demo.py中那样。
注意
一些字符在TeX中需要特别转义,例如:
#$%&~_^\{}\(\)\[\]
所以,这些字符会根据 rcParamtext.usetex标志位而表现不同。
在TeX中使用Unicode
也可以在LaTeX文本管理器中使用unicode字符串,这里是
从tex_unicode_demo.py中获取的示例:
使用LaTeX渲染文本
161

#-*-coding:utf-8-*-
"""
Thisdemoistex_demo.pymodifiedtohaveunicode.Seethatfile
for
moreinformation.
"""
from__future__importunicode_literals
importnumpyasnp
importmatplotlib
matplotlib.rcParams['text.usetex']=True
matplotlib.rcParams['text.latex.unicode']=True
importmatplotlib.pyplotasplt
plt.figure(1,figsize=(6,4))
ax=plt.axes([0.1,0.1,0.8,0.7])
t=np.arange(0.0,1.0+0.01,0.01)
s=np.cos(2*2*np.pi*t)+2
plt.plot(t,s)
plt.xlabel(r'\textbf{time(s)}')
plt.ylabel('\\textit{Velocity(\u00B0/sec)}',fontsize=16)
plt.title(r'\TeX\isNumber$\displaystyle\sum_{n=1}^\infty'
r'\frac{-e^{i\pi}}{2^n}$!',fontsize=16,color='r')
plt.grid(True)
plt.show()
Postscript选项
使用LaTeX渲染文本
162

为了生成可以嵌入到新LaTeX文档中的postscript封装文件,matplotlib的默认行
为是提取输出,这会删除LaTeX使用的一些postscript操作符,这些操作符在eps
文件中是非法的。此步骤产生的结果对于一些用户可能是不可接受的,因为文本被
粗略地光栅化并且被转换为位图,而不像标准Postscript那样是可缩放的,并且文
本是不可搜索的。一种解决方法是在你的 rc设置中将 ps.distiller.res设置
为较高的值(可能为6000),这将产生较大的文件,但可能看起来更好并能够合
理缩放。更好的解决方法需要Poppler或Xpdf,可以通过
将ps.usedistillerrc设置更改为 xpdf来激活。此替代方案产生postscript
而不光栅化文本,因此它能够正确缩放,可以在AdobeIllustrator中编辑,并搜
索pdf文档中的文本。
可能的问题
在Windows上,可能需要修改 PATH环境变量来包含latex,dvipng和
ghostscript可执行文件的目录。详细信息请参阅环境变量和在Windows中设
置环境变量。
使用MiKTeX与ComputerModern字体,如果你得到奇怪的*Agg和PNG结
果,访问 MiKTeX/Options并更新你的格式文件。
字体在屏幕上看起来糟糕。你可能正在运行MacOS,在mac上的老版本
dvipng运行着一些有趣的事情。在你的 matplotlibrc文件中设
置text.dvipnghack:True。
在Ubuntu和Gentoo上,texlive基本安装不附带type1cm包。你可能需要安
装一些额外的包,来获得所有与其它LaTeX分发版捆绑的特性。
matplotlib已经取得了一些进展,所以可以直接使用 dvi文件进行文本布局。
这允许LaTeX用于具有 pdf和svg后端的文本布局,以及*Agg和PS后
端。在将来,LaTeX安装可能是唯一的外部依赖。
故障排除
尝试删除 .matplotlib/tex.cache目录。如果你不知道 .matplotlib在
哪里,请参见matplotlib配置和缓存目录位置。
确保LaTeX,dvipng和ghostscript都正常工作,并存在于你的 PATH中。
确保你想要做的事情在LaTeX文档中可实现,你的LaTeX语法是有效的,并
且你正在使用原始字符串,如果必要,以避免意外的转义序列。
邮件列表上报告的大多数问题已通过升级Ghostscript来清除。如果可能的
话,请尝试升级到最新版本,然后向列表报告问题。
text.latex.preamblerc设置不受官方支持。此选项提供了大量的灵活性
和导致问题的许多方法。请在向邮件列表报告问题之前禁用此选项。
如果仍需要帮助,请参阅获取帮助。
使用LaTeX渲染文本
163

XeLaTeX/LuaLaTeX设置
原文:TypesettingWithXeLaTeX/LuaLaTeX
译者:飞龙
协议:CCBY-NC-SA4.0
使用pgf后端,matplotlib可以将图形导出为可以使用pdflatex,xelatex或
lualatex处理的pgf绘图命令。XeLaTeX和LuaLaTeX具有完整的unicode支持,
可以使用安装在操作系统中的任何字体,利用OpenType,AAT和Graphite的高
级排版功能。由plt.savefig('figure.pgf')创建的Pgf图片可以作为原始命
令嵌入到LaTeX文档中。图形也可以通过切换到该后端,直接编译并使
用plt.savefig('figure.pdf')保存到PDF。
matplotlib.use('pgf')
或者为处理PDF输出而注册它:
frommatplotlib.backends.backend_pgfimportFigureCanvasPgf
matplotlib.backend_bases.register_backend('pdf',FigureCanvasPgf
)
第二种方法允许你继续使用常规的交互式后端,并从图形用户界面保存xelatex,
lualatex或pdflatex编译的PDF文件。
Matplotlib的pgf支持需要最新的LaTeX安装,包括TikZ/PGF软件包(如
TeXLive),最好安装XeLaTeX或LuaLaTeX。如果你的系统上存在pdftocairo或
ghostscript,也可以选择将图形保存为PNG图像。所有应用程序的可执行文件必
须位于 PATH中。
控制pgf后端行为的Rc参数:
参数 文档
pgf.preamble 包含在LaTeX序言中的行
pgf.rcfonts 使用fontspec软件包从rc参数设置字体
pgf.texsystem xelatex(默认), lualatex或者 pdflatex
XeLaTeX/LuaLaTeX设置
164

注意
TeX定义了一系列特殊字符,例如:
#$%&~_^\{}
通常,这些字符必须正确转义。一些字符( _,^,%)会自动在数学环
境之外转义。
字体规定
用于获取文本元素大小,或将图形编译为PDF的字体通常在matplotlibrc参数中
定义。你还可以通过清
除font.serif,font.sans-serif或font.monospace的列表来使用LaTeX
默认的ComputerModern字体。请注意,这些字体的字形覆盖范围非常有限。如
果要保留ComputerModern字体,但需要扩展Unicode编码支持,请考虑安装
ComputerModernUnicode字体CMUSerif,CMUSansSerif等。
保存到 .pgf时,matplotlib用于图形布局的字体配置包含在文本文件的标题中。
#-*-coding:utf-8-*-
importmatplotlibasmpl
mpl.use("pgf")
pgf_with_rc_fonts={
"font.family":"serif",
"font.serif":[],#uselatexdefaultseri
ffont
"font.sans-serif":["DejaVuSans"],#useaspecificsans-se
riffont
}
mpl.rcParams.update(pgf_with_rc_fonts)
importmatplotlib.pyplotasplt
plt.figure(figsize=(4.5,2.5))
plt.plot(range(5))
plt.text(0.5,3.,"serif")
plt.text(0.5,2.,"monospace",family="monospace")
plt.text(2.5,2.,"sans-serif",family="sans-serif")
plt.text(2.5,1.,"comicsans",family="ComicSansMS")
plt.xlabel(u"μisnot$\\mu$")
plt.tight_layout(.5)
XeLaTeX/LuaLaTeX设置
165

自定义序言
通过将你的命令添加到序言中,你可以完全自定义它。如果要配置数学字体(例如
使用unicode-math)或加载其他软件包,请使用 pgf.preamble参数。此外,如
果你想自己做字体配置,而不是使用rc参数中指定的字体,请确保禁
用pgf.rcfonts。
XeLaTeX/LuaLaTeX设置
166

#-*-coding:utf-8-*-
from__future__import(absolute_import,division,print_functio
n,
unicode_literals)
importsix
importmatplotlibasmpl
mpl.use("pgf")
pgf_with_custom_preamble={
"font.family":"serif",#useserif/mainfontfortexteleme
nts
"text.usetex":True,#useinlinemathforticks
"pgf.rcfonts":False,#don'tsetupfontsfromrcparamete
rs
"pgf.preamble":[
"\\usepackage{units}",#loadadditionalpackag
es
"\\usepackage{metalogo}",
"\\usepackage{unicode-math}",#unicodemathsetup
r"\setmathfont{xits-math.otf}",
r"\setmainfont{DejaVuSerif}",#seriffontviapreamble
]
}
mpl.rcParams.update(pgf_with_custom_preamble)
importmatplotlib.pyplotasplt
plt.figure(figsize=(4.5,2.5))
plt.plot(range(5))
plt.xlabel("unicodetext:я,ψ,€,ü,\\unitfrac[10]{°}{μm}")
plt.ylabel("\\XeLaTeX")
plt.legend(["unicodemath:$λ=∑_i^∞μ_i^2$"])
plt.tight_layout(.5)
XeLaTeX/LuaLaTeX设置
167

选择TeX系统
matplotlib使用的TeX系统由 pgf.texsystem参数选择。可能的值
为xelatex(默认值), lualatex和pdflatex。请注意,当选
择pdflatex时,必须在序言中配置字体和unicode处理。
#-*-coding:utf-8-*-
importmatplotlibasmpl
mpl.use("pgf")
pgf_with_pdflatex={
"pgf.texsystem":"pdflatex",
"pgf.preamble":[
r"\usepackage[utf8x]{inputenc}",
r"\usepackage[T1]{fontenc}",
r"\usepackage{cmbright}",
]
}
mpl.rcParams.update(pgf_with_pdflatex)
importmatplotlib.pyplotasplt
plt.figure(figsize=(4.5,2.5))
plt.plot(range(5))
plt.text(0.5,3.,"serif",family="serif")
plt.text(0.5,2.,"monospace",family="monospace")
plt.text(2.5,2.,"sans-serif",family="sans-serif")
plt.xlabel(u"μisnot$\\mu$")
plt.tight_layout(.5)
故障排除
请注意,在一些Linux发行版和MiKTeX安装中发现的TeX包已经过时了。确保更
新你的软件包目录并升级或安装最新的TeX发行版。在Windows上,可能需要修
改PATH环境变量来包含latex,dvipng和ghostscript可执行文件的目录。详细信
XeLaTeX/LuaLaTeX设置
168

息请参阅环境变量和在窗口中设置环境变量。Windows上的限制会导致后端保留
由应用程序打开的文件句柄。因此,可能无法删除相应的文件,直到应用程序关闭
(参见 #1324)。有时保存到png图像的图形中的字体非常糟糕。这在
pdftocairo工具不可用,并且ghostscript用于pdf到png的转换时发生。确保你
想要做的事情在LaTeX文档中可实现,你的LaTeX语法是有效的,并且你正在使
用原始字符串,如果必要的话,避免意外的转义序列。pgf.preamblerc设置提
供了大量的灵活性,以及导致问题的许多方法。遇到问题时,尝试最小化或禁用自
定义序言。配置unicode-math环境可能有点棘手。例如TeXLive分发版提供了一
组通常不在系统范围内安装的数学字体。与LuaLatex不同的是,XeTeX不能根据
名字找到这些字体,这就是你可能必须指定 \setmathfont{xits-math.otf},
而不是 \setmathfont{XITSMath}的原因,或者使字体可用于你的操作系统。更
多详细信息请参阅这个 tex.stackexchange.com的问题。如果matplotlib使用的
字体配置不同于你的LaTeX文档中的字体设置,则导入图形中的文本元素对齐可能
会关闭。如果你不确定matplotlib用于布局的字体,请检查 .pgf文件的标题。如
果图中有很多对象,矢量图像和 .pgf文件可能变得臃肿。这可能是图像处理或非
常大的散点图的情况。在极端情况下,这可能导致TeX内存不
足: TeXcapacityexceeded,sorry(TeX容量过大,对不起)。你可以配置
LaTeX来增加可用于生成 .pdf图像的内存量,请
见tex.stackexchange.com上讨论的问题。另一种方法是使
用rasterized=True关键字,或者根据本示例
的.set_rasterized(True)『栅格化』图形的某些导致问题部分。如果你仍需
要帮助,请参阅获取帮助。
XeLaTeX/LuaLaTeX设置
169

颜色
颜色
170

指定颜色
原文:SpecifyingColors
译者:飞龙
协议:CCBY-NC-SA4.0
在matplotlib的几乎所有地方,用户都可以指定颜色,它可以以如下形式提供:
RGB或者RGBA浮点值元组, [0,1]之间,例如 (0.1,0.2,0.5)或
者(0.1,0.2,0.5,0.3)。
RGB或者RGBA十六进制字符串,例如 #0F0F0F或者 #0F0F0F0F。
[0,1]之间的浮点值的字符串表示,用于表示灰度,例如 0.5。
{'b','g','r','c','m','y','k','w'}之一。
X11/CSS4颜色名称。
XKCD颜色之一,以 'xkcd:'为前缀,例如 'xkcd:skyblue'。
{'C0','C1','C2','C3','C4','C5','C6','C7','C8','C9'}之
一。
{'tab:blue','tab:orange','tab:green','tab:red','tab:purple','tab:brown','tab:pink','tab:gray','tab:olive','tab:cyan'}
之一。这是T10调色板的Tableau颜色(默认的色相环)。
所有颜色字符串都是大小写敏感的。
CN颜色选择
颜色可以通由匹配正则表达式 C[0-9]的字符串来指定。这可以在任何当前接受
颜色的地方传递,并且可以在 matplotlib.Axes.plot的format-string中用
作“单个字符颜色”。
单个数字是默认属性环的索引
(matplotlib.rcParams['axes.prop_cycle'])。如果属性环不包
括'color',则返回黑色。在创建艺术家时会对颜色求值。例如:
指定颜色
171

importnumpyasnp
importmatplotlib.pyplotasplt
importmatplotlibasmpl
th=np.linspace(0,2*np.pi,128)
defdemo(sty):
mpl.style.use(sty)
fig,ax=plt.subplots(figsize=(3,3))
ax.set_title('style:{!r}'.format(sty),color='C0')
ax.plot(th,np.cos(th),'C1',label='C1')
ax.plot(th,np.sin(th),'C2',label='C2')
ax.legend()
demo('default')
指定颜色
172

指定颜色
173

选择颜色表
174

颜色表标准化
175

自定义matplotlib
原文:Customizingmatplotlib
译者:飞龙
协议:CCBY-NC-SA4.0
使用样式表自定义绘图
style包为易于切换的绘图『样式』增加了支持,它们与 matplotlibrc文件参
数相同。
有一些预定义样式由 matplotlib提供。例如,有一个名为『ggplot』的预定义
样式,它模拟 ggplot(R的一种流行的绘图软件包)的美学。为了使用此样
式,只需添加:
>>>importmatplotlib.pyplotasplt
>>>plt.style.use('ggplot')
为了列出所有可用样式,使用:
>>>print(plt.style.available)
定义你自己的样式
你可以创建自定义样式,并通过以样式表的路径或URL调用 style.use来使用它
们。或者,如果将 <style-name>mplstyle文件添加
到mpl_configdir/stylelib中,你可以通过调
用style.use(<style-name>)重复使用自定义样式表。默认情况
下mpl_configdir应该是 ~/.config/matplotlib,但你可以使
用matplotlib.get_configdir()检查你的位置,你可能需要创建这个目录。请
注意,如果样式具有相同的名称, mpl_configdir/stylelib中的自定义样式表
将覆盖由 matplotlib定义的样式表。
例如,你可能想要使用以下命令创
建mpl_configdir/stylelib/presentation.mplstyle:
自定义matplotlib
176

axes.titlesize:24
axes.labelsize:20
lines.linewidth:3
lines.markersize:10
xtick.labelsize:16
ytick.labelsize:16
然后,当你想要将一个为纸张设计的地图迁移到演示文档中时,你可以添加:
>>>importmatplotlib.pyplotasplt
>>>plt.style.use('presentation')
组合样式
样式表为组合在一起而设计。因此,你可以拥有一个自定义颜色的样式表和一个单
独的样式表,用于更改演示文档的元素大小。这些样式可以通过传递样式列表轻松
组合:
>>>importmatplotlib.pyplotasplt
>>>plt.style.use(['dark_background','presentation'])
请注意,右侧的样式将覆盖已经由左侧样式定义的值。
临时样式
如果只想对特定的代码块使用样式,但不想更改全局样式,那么样式包提供了一个
上下文管理器,用于将更改限制于特定范围。要隔离你的样式更改,你可以编写以
下内容:
>>>importnumpyasnp
>>>importmatplotlib.pyplotasplt
>>>
>>>withplt.style.context(('dark_background')):
>>>plt.plot(np.sin(np.linspace(0,2*np.pi)),'r-o')
>>>
>>>#Someplottingcodewiththedefaultstyle
>>>
>>>plt.show()
自定义matplotlib
177

交互式绘图
交互式绘图
178

交互式导航
原文:Interactivenavigation
译者:飞龙
协议:CCBY-NC-SA4.0
所有图形窗口都带有导航工具栏,可用于浏览数据集。以下是工具栏底部的每个按
钮的说明:
Home(首页)、 Forward(前进)和 Back(后退)按钮:
这些类似于Web浏览器的前进和后退按钮。它们用于在之前定义的视图之间来回
浏览。它们没有意义,除非你已经使用平移和缩放按钮访问了其他地方。这类似
于尝试在访问新页面之前单击Web浏览器上的返回-什么都不会发生。首页总是
你第一个浏览的页面,以及你的数据的默认视图。对
于Home,Forward和Back,应该将其看做Web浏览器,其中的数据视图是
网页。使用 Pan和Zoom来定义新视图。
Pan/Zoom(平移/缩放)按钮
此按钮有两种模式:平移和缩放。单击工具栏按钮激活平移和缩放,然后将鼠标放
在轴域的某个地方。按住鼠标左键并将其拖动到新位置来平移图形。当你释放它
时,你按下的点处的数据将移动到你释放的点。如果在平移时按 'x'或'y',
移动会分别限制在 x或y轴。按鼠标右键并将其拖动到新位置来进行缩放。向
右移动使 x轴成比例放大,或者向左移动成比例缩小。y轴和上/下移动同上。
开始缩放时鼠标下的点会保持静止,你可以缩放图形中的其它任意点。你可以使用
快捷键 'x','y'或CONTROL分别将缩放约束为 x轴, y轴或保留宽高比。
使用极坐标绘图时,平移和缩放功能的行为不同。可以使用鼠标左键拖动半径轴标
签。可以使用鼠标右键放大和缩小半径刻度。
Zoom-to-rectangle(缩放到矩形)按钮
单击此工具栏按钮以激活此模式。将鼠标放在轴域的某处,然后按鼠标左键。在
按住按钮的同时拖动鼠标到新位置并释放。轴域会放大并限制于你定义的矩形。
在此模式中还有一个实验性的 zoomouttorectangle(缩小到矩形),使用右
键,将整个轴域缩小并放置在矩形定义的区域中。
交互式导航
179

Subplot-configuration(子图配置)按钮
使用此工具配置子图的参数:左边距,右边距,上边距,下边距,行间隔和列间
隔。
Save(保存)按钮
单击此按钮可启动文件保存对话框。你可以使用以下扩展名保存文
件: png,ps,eps,svg和pdf。
浏览快捷键
下表包含所有默认的快捷键,可以使用 matplotlibrc(#keymap.*)覆盖。
命令 快捷键
主页/重置 h、r或home
后退 c、左箭头或 backspace
前进 v或右箭头
平移/缩放 p
缩放到矩形 o
保存 ctrl+s
切换全屏 ctrl+f
关闭绘图 ctrl+w
将平移/缩放限制于 x轴 使用鼠标平移/缩放时按住 x
将平移/缩放限制于 y轴 使用鼠标平移/缩放时按住 y
保留宽高比 使用鼠标平移/缩放时按住 CONTROL
切换网格 鼠标在轴域上时按下 g
切换 x轴刻度(对数/线性) 鼠标在轴域上时按下 L或k
切换 y轴刻度(对数/线性) 鼠标在轴域上时按下 l
如果你使用 matplotlib.pyplot,则会为每个图形自动创建工具栏。如果你正
在编写自己的用户界面代码,则可以将工具栏添加为窗口小部件。确切的语法取决
于你的UI,但在`matplotlib/examples/user_interfaces目录中有每个受支持的UI的
示例。这里是一些GTK的示例代码:
交互式导航
180

importgtk
frommatplotlib.figureimportFigure
frommatplotlib.backends.backend_gtkaggimportFigureCanvasGTKAg
gasFigureCanvas
frommatplotlib.backends.backend_gtkaggimportNavigationToolbar
2GTKAggasNavigationToolbar
win=gtk.Window()
win.connect("destroy",lambdax:gtk.main_quit())
win.set_default_size(400,300)
win.set_title("EmbeddinginGTK")
vbox=gtk.VBox()
win.add(vbox)
fig=Figure(figsize=(5,4),dpi=100)
ax=fig.add_subplot(111)
ax.plot([1,2,3])
canvas=FigureCanvas(fig)#agtk.DrawingArea
vbox.pack_start(canvas)
toolbar=NavigationToolbar(canvas,win)
vbox.pack_start(toolbar,False,False)
win.show_all()
gtk.main()
交互式导航
181

在Pythonshell中使用Matplotlib
原文:Usingmatplotlibinapythonshell
译者:飞龙
协议:CCBY-NC-SA4.0
警告
该页面的内容已严重过时。
默认情况下,matplotlib将绘图延迟到脚本结束,因为绘图可能是开销大的操作,
并且你可能不想在每次更改单个属性时更新绘图,而是只在所有属性更改后更新一
次。
但是在pythonshell中工作时,通常需要用每个命令更新绘图,例如,在更
改xlabel()或一行的标记样式之后。虽然这在概念上很简单,但在实践中它可
能很棘手,因为matplotlib在底层是一个图形用户界面应用程序,并拥有一些技
巧,使应用程序在一个pythonshell正常工作。
使用IPython解决
注意
这里描述的模式出于历史原因仍然存在,但强烈建议不要使用。它污染函数的
命名空间,会影响python内建设施,并可能导致错误难以跟踪。要获得
IPython集成而无需导入,使用 %matplotlib魔术命令是首个选择。参见
ipython文档。
幸运的是,一个增强的交互式pythonshell,ipython已经找出了所有这些技巧,并
且可被matplotlib感知,所以当你在pylab模式下启动ipython。
johnh@flag:~>ipython
Python2.4.5(#4,Apr122008,09:09:16)
IPython0.9.0--AnenhancedInteractivePython.
In[1]:%pylab
Welcometopylab,amatplotlib-basedPythonenvironment.
Formoreinformation,type'help(pylab)'.
In[2]:x=randn(10000)
In[3]:hist(x,100)
在PythonShell中使用matplotlib
182

它为你设置一切使交互式绘图工作,就像你期望的那样。调用 figure()并弹出
图形窗口,调用 plot()使你的数据出现在图形窗口中。
注意在上面的例子中,我们没有导入任何matplotlib名称,因为在pylab模式下,
ipython将自动导入它们。ipython还为你启用交互模式,这会导致每个pyplot命
令触发图形更新,并且还提供了一个matplotlib感知的运行命令,来高效运行
matplotlib脚本。ipython在运行命令期间关闭交互模式,然后在运行结束时恢复交
互状态,以便你可以手动继续调整图形。
ipython已经嵌入了很多最近的作品,从pylab支持,到各种GUI应用程序,所以
请检查ipython邮件列表的最新状态。
其它Python解释器
如果你不能使用ipython,并且仍然想在交互式pythonshell使用
matplotlib/pylab,例如,plain-ole标准的python交互式解释器,你将需要了解什
么是matplotlib后端。
有了TkAgg后端,它使用Tkinter用户界面工具包,你可以从任意的非guipython
shell使用matplotlib。只需在你的 matplotlibrc文件中设
置backend:TkAgg和interactive:True(请参阅自定义matplotlib)并启
动python。然后:
>>>frompylabimport*
>>>plot([1,2,3])
>>>xlabel('himom')
应该能够开箱即用。这也可能适用于最新版本的qt4agg和gtkagg后端,以及
Macintosh上的macosx后端。注意,在批处理模式下,即从脚本制作图形时,交
互模式可能很慢,因为它用每个命令重绘图形。因此,你可能需要仔细考虑,然后
通过 matplotlibrc文件而不是使用下一节中列出的函数,使其作为默认行为。
Guishell问题最多,因为它们必须运行主循环,但是交互式绘图也涉及主循环。
Ipython已经为matplotlib主后端解决了这一切问题。可能有其他shell和IDE也
可以在交互模式下使用matplotlib,但一个明显的候选项不会:pythonIDLEIDE是
一个不支持pylab交互模式的Tkintergui应用程序,无论后端是什么。
控制交互式更新
pyplot接口的 interactive属性控制是否在每个 pyplot命令上绘制图画
布。如果 interactive是False,那么每个 plot命令都会更新图形状态,但
只会在显式调用 draw()时绘制。当interactive为True时,每
个pyplot命令都会触发绘制。
pyplot接口提供了4个有助于交互式控制的命令。
在PythonShell中使用matplotlib
183

isinteractive()
返回交互式设置。 True|False。
ion()
将交互式模式打开。
ioff()
将交互式模式关闭。
draw()
强制图形重新绘制。
当处理绘图开销很大的大型图形时,你可能希望临时关闭matplotlib的交互式设置
来避免性能损失:
>>>#createbig-expensive-figure
>>>ioff()#turnupdatesoff
>>>title('nowhowmuchwouldyoupay?')
>>>xticklabels(fontsize=20,color='green')
>>>draw()#forceadraw
>>>savefig('alldone',dpi=300)
>>>close()
>>>ion()#turnupdatingbackon
>>>plot(rand(20),mfc='g',mec='r',ms=40,mew=4,ls='--',lw=3
)
在PythonShell中使用matplotlib
184

事件处理及拾取
原文:Eventhandlingandpicking
译者:飞龙
协议:CCBY-NC-SA4.0
matplotlib使用了许多用户界面工具包(wxpython,tkinter,qt4,gtk和
macosx),为了支持交互式平移和缩放图形等功能,拥有一套API通过按键和鼠
标移动与图形交互,并且『GUI中立』,对开发人员十分有帮助,所以我们不必重
复大量的代码来跨不同的用户界面。虽然事件处理API是GUI中立的,但它是基
于GTK模型,这是matplotlib支持的第一个用户界面。与标准GUI事件相比,被
触发的事件也比matplotlib丰富一些,例如包括发生事件
的matplotlib.axes.Axes的信息。事件还能够理解matplotlib坐标系,并且在
事件中以像素和数据坐标为单位报告事件位置。
事件连接
要接收事件,你需要编写一个回调函数,然后将你的函数连接到事件管理器,它
是FigureCanvasBase的一部分。这是一个简单的例子,打印鼠标点击的位置和
按下哪个按钮:
fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(np.random.rand(10))
defonclick(event):
print('button=%d,x=%d,y=%d,xdata=%f,ydata=%f'%
(event.button,event.x,event.y,event.xdata,event.yd
ata))
cid=fig.canvas.mpl_connect('button_press_event',onclick)
FigureCanvas的方法 mpl_connect()返回一个连接 id,它只是一个整数。
当你要断开回调时,只需调用:
fig.canvas.mpl_disconnect(cid)
注意
画布仅保留回调的弱引用。因此,如果回调是类实例的方法,你需要保留对该
实例的引用。否则实例将被垃圾回收,回调将消失。
事件处理及拾取
185

以下是可以连接到的事件,在事件发生时发回给你的类实例以及事件描述:
事件名称 类和描述
'button_press_event' MouseEvent-鼠标按钮被按下
'button_release_event' MouseEvent-鼠标按钮被释放
'draw_event' DrawEvent-画布绘图
'key_press_event' KeyEvent-按键被按下
'key_release_event' KeyEvent-按键被释放
'motion_notify_event' MouseEvent-鼠标移动
'pick_event' PickEvent-画布中的对象被选中
'resize_event' ResizeEvent-图形画布大小改变
'scroll_event' MouseEvent-鼠标滚轮被滚动
'figure_enter_event' LocationEvent-鼠标进入新的图形
'figure_leave_event' LocationEvent-鼠标离开图形
'axes_enter_event' LocationEvent-鼠标进入新的轴域
'axes_leave_event' LocationEvent-鼠标离开轴域
事件属性
所有matplotlib事件继承自基类 matplotlib.backend_bases.Event,储存以下
属性:
name
事件名称
canvas
生成事件的 FigureCanvas实例
guiEvent
触发matplotlib事件的GUI事件
最常见的事件是按键按下/释放事件、鼠标按下/释放和移动事件。处理这些事件
的KeyEvent和MouseEvent类都派生自 LocationEvent,它具有以下属性:
x
x位置,距离画布左端的像素
事件处理及拾取
186

y
y位置,距离画布底端的像素
inaxes
如果鼠标经过轴域,则为 Axes实例
xdata
鼠标的 x坐标,以数据坐标为单位
ydata
鼠标的 y坐标,以数据坐标为单位
但我们看一看画布的简单示例,其中每次按下鼠标时都会创建一条线段。
frommatplotlibimportpyplotasplt
classLineBuilder:
def__init__(self,line):
self.line=line
self.xs=list(line.get_xdata())
self.ys=list(line.get_ydata())
self.cid=line.figure.canvas.mpl_connect('button_press_
event',self)
def__call__(self,event):
print('click',event)
ifevent.inaxes!=self.line.axes:return
self.xs.append(event.xdata)
self.ys.append(event.ydata)
self.line.set_data(self.xs,self.ys)
self.line.figure.canvas.draw()
fig=plt.figure()
ax=fig.add_subplot(111)
ax.set_title('clicktobuildlinesegments')
line,=ax.plot([0],[0])#emptyline
linebuilder=LineBuilder(line)
plt.show()
我们刚刚使用的 MouseEvent是一个 LocationEvent,因此我们可以访
问event.x和event.xdata中的数据和像素坐标。除了 LocationEvent属
性,它拥有:
button
按下的按钮, None、1、2、3、'up'、'down'('up'、'down'用于滚
动事件)
事件处理及拾取
187

key
按下的键, None,任何字符, 'shift'、'win'或者 'control'
可拖拽的矩形练习
编写使用 Rectangle实例初始化的可拖动矩形类,但在拖动时会移动
其x,y位置。提示:你需要存储矩形的原始 xy位置,存储为 rect.xy并
连接到按下,移动和释放鼠标事件。当鼠标按下时,检查点击是否发生在你的矩形
上(见 matplotlib.patches.Rectangle.contains()),如果是,存储矩
形xy和数据坐标为单位的鼠标点击位置。在移动事件回调中,计算鼠标移动
的deltax和deltay,并将这些增量添加到存储的原始矩形,并重新绘图。在
按钮释放事件中,只需将所有你存储的按钮按下数据重置为 None。
这里是解决方案:
importnumpyasnp
importmatplotlib.pyplotasplt
classDraggableRectangle:
def__init__(self,rect):
self.rect=rect
self.press=None
defconnect(self):
'connecttoalltheeventsweneed'
self.cidpress=self.rect.figure.canvas.mpl_connect(
'button_press_event',self.on_press)
self.cidrelease=self.rect.figure.canvas.mpl_connect(
'button_release_event',self.on_release)
self.cidmotion=self.rect.figure.canvas.mpl_connect(
'motion_notify_event',self.on_motion)
defon_press(self,event):
'onbuttonpresswewillseeifthemouseisoverusand
storesomedata'
ifevent.inaxes!=self.rect.axes:return
contains,attrd=self.rect.contains(event)
ifnotcontains:return
print('eventcontains',self.rect.xy)
x0,y0=self.rect.xy
self.press=x0,y0,event.xdata,event.ydata
defon_motion(self,event):
'onmotionwewillmovetherectifthemouseisoverus'
ifself.pressisNone:return
ifevent.inaxes!=self.rect.axes:return
x0,y0,xpress,ypress=self.press
dx=event.xdata-xpress
事件处理及拾取
188

dy=event.ydata-ypress
#print('x0=%f,xpress=%f,event.xdata=%f,dx=%f,x0+dx=%
f'%
#(x0,xpress,event.xdata,dx,x0+dx))
self.rect.set_x(x0+dx)
self.rect.set_y(y0+dy)
self.rect.figure.canvas.draw()
defon_release(self,event):
'onreleaseweresetthepressdata'
self.press=None
self.rect.figure.canvas.draw()
defdisconnect(self):
'disconnectallthestoredconnectionids'
self.rect.figure.canvas.mpl_disconnect(self.cidpress)
self.rect.figure.canvas.mpl_disconnect(self.cidrelease)
self.rect.figure.canvas.mpl_disconnect(self.cidmotion)
fig=plt.figure()
ax=fig.add_subplot(111)
rects=ax.bar(range(10),20*np.random.rand(10))
drs=[]
forrectinrects:
dr=DraggableRectangle(rect)
dr.connect()
drs.append(dr)
plt.show()
附加题:使用动画秘籍中讨论的动画blit技术,使动画绘制更快更流畅。
附加题解决方案:
#draggablerectanglewiththeanimationblittechniques;see
#http://www.scipy.org/Cookbook/Matplotlib/Animations
importnumpyasnp
importmatplotlib.pyplotasplt
classDraggableRectangle:
lock=None#onlyonecanbeanimatedatatime
def__init__(self,rect):
self.rect=rect
self.press=None
self.background=None
defconnect(self):
'connecttoalltheeventsweneed'
self.cidpress=self.rect.figure.canvas.mpl_connect(
事件处理及拾取
189

'button_press_event',self.on_press)
self.cidrelease=self.rect.figure.canvas.mpl_connect(
'button_release_event',self.on_release)
self.cidmotion=self.rect.figure.canvas.mpl_connect(
'motion_notify_event',self.on_motion)
defon_press(self,event):
'onbuttonpresswewillseeifthemouseisoverusand
storesomedata'
ifevent.inaxes!=self.rect.axes:return
ifDraggableRectangle.lockisnotNone:return
contains,attrd=self.rect.contains(event)
ifnotcontains:return
print('eventcontains',self.rect.xy)
x0,y0=self.rect.xy
self.press=x0,y0,event.xdata,event.ydata
DraggableRectangle.lock=self
#draweverythingbuttheselectedrectangleandstoret
hepixelbuffer
canvas=self.rect.figure.canvas
axes=self.rect.axes
self.rect.set_animated(True)
canvas.draw()
self.background=canvas.copy_from_bbox(self.rect.axes.b
box)
#nowredrawjusttherectangle
axes.draw_artist(self.rect)
#andblitjusttheredrawnarea
canvas.blit(axes.bbox)
defon_motion(self,event):
'onmotionwewillmovetherectifthemouseisoverus'
ifDraggableRectangle.lockisnotself:
return
ifevent.inaxes!=self.rect.axes:return
x0,y0,xpress,ypress=self.press
dx=event.xdata-xpress
dy=event.ydata-ypress
self.rect.set_x(x0+dx)
self.rect.set_y(y0+dy)
canvas=self.rect.figure.canvas
axes=self.rect.axes
#restorethebackgroundregion
canvas.restore_region(self.background)
#redrawjustthecurrentrectangle
axes.draw_artist(self.rect)
事件处理及拾取
190

#blitjusttheredrawnarea
canvas.blit(axes.bbox)
defon_release(self,event):
'onreleaseweresetthepressdata'
ifDraggableRectangle.lockisnotself:
return
self.press=None
DraggableRectangle.lock=None
#turnofftherectanimationpropertyandresetthebac
kground
self.rect.set_animated(False)
self.background=None
#redrawthefullfigure
self.rect.figure.canvas.draw()
defdisconnect(self):
'disconnectallthestoredconnectionids'
self.rect.figure.canvas.mpl_disconnect(self.cidpress)
self.rect.figure.canvas.mpl_disconnect(self.cidrelease)
self.rect.figure.canvas.mpl_disconnect(self.cidmotion)
fig=plt.figure()
ax=fig.add_subplot(111)
rects=ax.bar(range(10),20*np.random.rand(10))
drs=[]
forrectinrects:
dr=DraggableRectangle(rect)
dr.connect()
drs.append(dr)
plt.show()
鼠标进入和离开
如果希望在鼠标进入或离开图形时通知你,你可以连接到图形/轴域进入/离开事
件。下面是一个简单的例子,它改变了鼠标所在的轴域和图形的背景颜色:
事件处理及拾取
191

"""
Illustratethefigureandaxesenterandleaveeventsbychangin
gthe
framecolorsonenterandleave
"""
importmatplotlib.pyplotasplt
defenter_axes(event):
print('enter_axes',event.inaxes)
event.inaxes.patch.set_facecolor('yellow')
event.canvas.draw()
defleave_axes(event):
print('leave_axes',event.inaxes)
event.inaxes.patch.set_facecolor('white')
event.canvas.draw()
defenter_figure(event):
print('enter_figure',event.canvas.figure)
event.canvas.figure.patch.set_facecolor('red')
event.canvas.draw()
defleave_figure(event):
print('leave_figure',event.canvas.figure)
event.canvas.figure.patch.set_facecolor('grey')
event.canvas.draw()
fig1=plt.figure()
fig1.suptitle('mousehoveroverfigureoraxestotriggerevents'
)
ax1=fig1.add_subplot(211)
ax2=fig1.add_subplot(212)
fig1.canvas.mpl_connect('figure_enter_event',enter_figure)
fig1.canvas.mpl_connect('figure_leave_event',leave_figure)
fig1.canvas.mpl_connect('axes_enter_event',enter_axes)
fig1.canvas.mpl_connect('axes_leave_event',leave_axes)
fig2=plt.figure()
fig2.suptitle('mousehoveroverfigureoraxestotriggerevents'
)
ax1=fig2.add_subplot(211)
ax2=fig2.add_subplot(212)
fig2.canvas.mpl_connect('figure_enter_event',enter_figure)
fig2.canvas.mpl_connect('figure_leave_event',leave_figure)
fig2.canvas.mpl_connect('axes_enter_event',enter_axes)
fig2.canvas.mpl_connect('axes_leave_event',leave_axes)
plt.show()
事件处理及拾取
192

对象拾取
你可以通过设置艺术家的 picker属性(例如,matplotlib
Line2D,Text,Patch,Polygon,AxesImage等)来启用选择,
picker属性有多种含义:
None
选择对于该艺术家已禁用(默认)
boolean
如果为 True,则启用选择,当鼠标移动到该艺术家上方时,会触发事件
float
如果选择器是数字,则将其解释为点的ε公差,并且如果其数据在鼠标事件的ε
内,则艺术家将触发事件。对于像线条和补丁集合的一些艺术家,艺术家可以向生
成的选择事件提供附加数据,例如,在选择事件的ε内的数据的索引。
函数
如果拾取器是可调用的,则它是用户提供的函数,用于确定艺术家是否被鼠标事件
击中。签名为 hit,props=picker(artist,mouseevent),用于测试是否命
中。如果鼠标事件在艺术家上,返回 hit=True,props是一个属性字典,
它们会添加到 PickEvent属性。
通过设置 picker属性启用对艺术家进行拾取后,你需要连接到图画布
的pick_event,以便在鼠标按下事件中获取拾取回调。例如:
defpick_handler(event):
mouseevent=event.mouseevent
artist=event.artist
#nowdosomethingwiththis...
传给你的回调的 PickEvent事件永远有两个属性:
mouseevent
是生成拾取事件的鼠标事件。鼠标事件具有像 x和y(显示空间中的坐标,例
如,距离左,下的像素)和 xdata,ydata(数据空间中的坐标)的属性。此
外,你可以获取有关按下哪些按钮,按下哪些键,鼠标在哪个轴域上面等信息。详
细信息请参阅 matplotlib.backend_bases.MouseEvent。
artist
生成拾取事件的 Artist。
另外,像 Line2D和PatchCollection的某些艺术家可以将附加的元数据(如索
引)附加到满足选择器标准的数据中(例如,行中在指定ε容差内的所有点)
事件处理及拾取
193

简单拾取示例
在下面的示例中,我们将行选择器属性设置为标量,因此它表示以点为单位的容差
(72点/英寸)。当拾取事件位于距离线条的容差范围时,将调用 onpick回调函
数,并且带有在拾取距离容差内的数据顶点索引。我们的 onpick回调函数只打
印在拾取位置上的数据。不同的matplotlib艺术家可以将不同的数据附加
到PickEvent。例如, Line2D将ind属性作为索引附加到拾取点下面的行数
据中。有关 Line的PickEvent属性的详细信息,请参阅 pick()。这里是代
码:
importnumpyasnp
importmatplotlib.pyplotasplt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.set_title('clickonpoints')
line,=ax.plot(np.random.rand(100),'o',picker=5)#5points
tolerance
defonpick(event):
thisline=event.artist
xdata=thisline.get_xdata()
ydata=thisline.get_ydata()
ind=event.ind
points=tuple(zip(xdata[ind],ydata[ind]))
print('onpickpoints:',points)
fig.canvas.mpl_connect('pick_event',onpick)
plt.show()
拾取练习
创建含有100个数组的数据集,包含1000个高斯随机数,并计算每个数组的样本
平均值和标准差(提示: numpy数组具有 mean和std方法),并制作100个
均值与100个标准的 xy标记图。将绘图命令创建的线条连接到拾取事件,并绘
制数据的原始时间序列,这些数据生成了被点击的点。如果在被点击的点的容差范
围内存在多于一个点,则可以使用多个子图来绘制多个时间序列。
练习的解决方案:
事件处理及拾取
194

"""
computethemeanandstddevof100datasetsandplotmeanvsst
ddev.
Whenyouclickononeofthemu,sigmapoints,plottherawdata
from
thedatasetthatgeneratedthemeanandstddev
"""
importnumpyasnp
importmatplotlib.pyplotasplt
X=np.random.rand(100,1000)
xs=np.mean(X,axis=1)
ys=np.std(X,axis=1)
fig=plt.figure()
ax=fig.add_subplot(111)
ax.set_title('clickonpointtoplottimeseries')
line,=ax.plot(xs,ys,'o',picker=5)#5pointstolerance
defonpick(event):
ifevent.artist!=line:returnTrue
N=len(event.ind)
ifnotN:returnTrue
figi=plt.figure()
forsubplotnum,dataindinenumerate(event.ind):
ax=figi.add_subplot(N,1,subplotnum+1)
ax.plot(X[dataind])
ax.text(0.05,0.9,'mu=%1.3f\nsigma=%1.3f'%(xs[dataind],
ys[dataind]),
transform=ax.transAxes,va='top')
ax.set_ylim(-0.5,1.5)
figi.show()
returnTrue
fig.canvas.mpl_connect('pick_event',onpick)
plt.show()
事件处理及拾取
195

所选示例
所选示例
196

这个特性完善了绘制向量场的 quiver()函数。感谢TomFlanagan和TonyYou
添加 streamplot函数。
屏幕截图
202

详细信息和用法请参阅 matplotlib.ticker和matplotlib.dates。
金融图表
您可以通过结合matplotlib提供的各种绘图函数,布局命令和标签工具来创建复杂
的金融图表。以下示例模拟ChartDirector中的一个财务图:
源代码
地图示例
JeffWhitaker的Basemap附加工具包可以在许多不同的地图投影上绘制数据。此
示例展示了如何在直角投影上绘制轮廓,标记和文本,以NASA的“蓝色大理石”卫
星图像作为背景。
源代码
对数绘图
semilogx(),semilogy()和loglog()函数简化了对数绘图的创建。
源代码
屏幕截图
210

下轴使用 specgram()绘制其中一个EEG通道的频谱图。
有关将matplotlib嵌入不同工具包的示例,请参阅:
user_interfaces示例代码: embedding_in_gtk2.py
user_interfaces示例代码: embedding_in_wx2.py
user_interfaces示例代码: mpl_with_glade.py
user_interfaces示例代码: embedding_in_qt4.py
user_interfaces示例代码: embedding_in_tk.py
XKCD风格的手绘图
matplotlib支持 xkcd风格的绘图。
源代码
屏幕截图
216

屏幕截图
217

我们最喜欢的秘籍
原文:OurFavoriteRecipes
译者:飞龙
协议:CCBY-NC-SA4.0
这里是一个简短的教程,示例和代码片段的集合,展示了一些有用的经验和技巧,
来制作更精美的图像,并克服一些matplotlib的缺陷。
共享轴限制和视图
通常用于使两个或更多绘图共享一个轴,例如,两个子绘图具有时间作为公共轴。
当你平移和缩放一个绘图,你想让另一个绘图一起移动。为了方便这一点,
matplotlib轴支持 sharex和sharey属性。创建 subplot()或axes()实例
时,你可以传入一个关键字,表明要共享的轴。
In[96]:t=np.arange(0,10,0.01)
In[97]:ax1=plt.subplot(211)
In[98]:ax1.plot(t,np.sin(2*np.pi*t))
Out[98]:[<matplotlib.lines.Line2Dobjectat0x98719ec>]
In[99]:ax2=plt.subplot(212,sharex=ax1)
In[100]:ax2.plot(t,np.sin(4*np.pi*t))
Out[100]:[<matplotlib.lines.Line2Dobjectat0xb7d8fec>]
轻松创建子图
在matplotlib的早期版本中,如果你想使用pythonicAPI并创建一个 figure实
例,并从中创建一个 subplots网格,而且可能带有共享轴,它涉及大量的样板代
码。例如:
#oldstyle
fig=plt.figure()
ax1=fig.add_subplot(221)
ax2=fig.add_subplot(222,sharex=ax1,sharey=ax1)
ax3=fig.add_subplot(223,sharex=ax1,sharey=ax1)
ax3=fig.add_subplot(224,sharex=ax1,sharey=ax1)
我们最喜欢的秘籍
218

FernandoPerez提供了一个很好的顶级方法,来一次性创建 subplots()(注意
末尾的 s),并为所有子图开启 x和y共享。你可以单独解构来获取轴域:
#newstylemethod1;unpacktheaxes
fig,((ax1,ax2),(ax3,ax4))=plt.subplots(2,2,sharex=True,
sharey=True)
ax1.plot(x)
或将它们作为行数乘列数的对象数组返回,支持numpy索引:
#newstylemethod2;useanaxesarray
fig,axs=plt.subplots(2,2,sharex=True,sharey=True)
axs[0,0].plot(x)
修复常见的日期问题
matplotlib允许你本地绘制pythondatetime实例,并且在大多数情况下,可以很好
地挑选刻度位置和字符串格式。但有几件事情它不能妥善处理,这里有一些技巧,
用于帮助你解决他们。我们将在 numpy记录数组中加载一些包
含datetime.date对象的示例日期数据:
In[63]:datafile=cbook.get_sample_data('goog.npy')
In[64]:r=np.load(datafile).view(np.recarray)
In[65]:r.dtype
Out[65]:dtype([('date','|O4'),('','|V4'),('open','<f8'),
('high','<f8'),('low','<f8'),('close','<f8'
),
('volume','<i8'),('adj_close','<f8')])
In[66]:r.date
Out[66]:
array([2004-08-19,2004-08-20,2004-08-23,...,2008-10-10,2008
-10-13,
2008-10-14],dtype=object)
字段日期的 numpy记录数组的 dtype是|O4,这意味着它是一个4字节的
python对象指针;在这种情况下,对象是 datetime.date实例,当我们在ipython
终端窗口中打印一些样本时,我们可以看到。
如果你绘制数据,
我们最喜欢的秘籍
219

In[67]:plot(r.date,r.close)
Out[67]:[<matplotlib.lines.Line2Dobjectat0x92a6b6c>]
你会看到x轴标签重合到一起。
另一个麻烦是,如果你将鼠标悬停在窗口上,并在x和y坐标处查看matplotlib工
具栏(交互式导航)的右下角,你会看到x位置的格式与刻度标签的格式相同,例
如,『Dec2004』。我们想要的是工具栏中的位置具有更高的精确度,例如,鼠
标悬停在上面时给我们确切的日期。为了解决第一个问题,我们可以使
用matplotlib.figure.Figure.autofmt_xdate()。修复第二个问题,我们可以
使用 ax.fmt_xdata属性,该属性可以设置为任何接受标量并返回字符串的函
数。matplotlib有一些内置的日期格式化器,所以我们将使用其中的一个。
plt.close('all')
fig,ax=plt.subplots(1)
ax.plot(r.date,r.close)
#rotateandaligntheticklabelssotheylookbetter
fig.autofmt_xdate()
#useamoreprecisedatestringforthexaxislocationsinthe
#toolbar
importmatplotlib.datesasmdates
ax.fmt_xdata=mdates.DateFormatter('%Y-%m-%d')
plt.title('fig.autofmt_xdatefixesthelabels')
我们最喜欢的秘籍
220

现在,当你将鼠标悬停在绘制的数据上,你将在工具栏中看到如 2004-12-01的
日期格式字符串。
透明度填充
fill_between()函数在最小和最大边界之间生成阴影区域,用于展示范围。它
有一个非常方便的参数,将填充范围与逻辑范围组合,例如,以便仅填充超过某个
阈值的曲线。=
基本上, fill_between可以用来增强图形的视觉外观。让我们比较两个财务-时
间图表,左边是一个简单的线框图,右边是一个填充图。
我们最喜欢的秘籍
221

Alpha通道在这里不是必需的,但它可以用来软化颜色,创建更具视觉吸引力的绘
图。在其他示例中,我们将在下面看到,Alpha通道在功能上有用,因为阴影区域
可以重叠,Alpha允许你同时看到两者。注意,postscript格式不支持alpha(这是
一个postscript限制,而不是一个matplotlib限制),因此,当使用alpha时,将
你的数字保存在PNG,PDF或SVG中。
我们的下一个例子是计算随机漫步的两个群体,它们具有不同的正态分布平均值和
标准差,足迹会从中绘制。我们使用共享区域来绘制群体的平均位置的加/减一个标
准差。这里的Alpha通道是有用的,不只是为了审美。
我们最喜欢的秘籍
222

importmatplotlib.pyplotasplt
importnumpyasnp
Nsteps,Nwalkers=100,250
t=np.arange(Nsteps)
#an(NstepsxNwalkers)arrayofrandomwalksteps
S1=0.002+0.01*np.random.randn(Nsteps,Nwalkers)
S2=0.004+0.02*np.random.randn(Nsteps,Nwalkers)
#an(NstepsxNwalkers)arrayofrandomwalkerpositions
X1=S1.cumsum(axis=0)
X2=S2.cumsum(axis=0)
#Nstepslengtharraysempiricalmeansandstandarddeviationso
fboth
#populationsovertime
mu1=X1.mean(axis=1)
sigma1=X1.std(axis=1)
mu2=X2.mean(axis=1)
sigma2=X2.std(axis=1)
#plotit!
fig,ax=plt.subplots(1)
ax.plot(t,mu1,lw=2,label='meanpopulation1',color='blue')
ax.plot(t,mu2,lw=2,label='meanpopulation2',color='yellow')
ax.fill_between(t,mu1+sigma1,mu1-sigma1,facecolor='blue',alp
ha=0.5)
ax.fill_between(t,mu2+sigma2,mu2-sigma2,facecolor='yellow',a
lpha=0.5)
ax.set_title('randomwalkersempirical$\mu$and$\pm\sigma$in
terval')
ax.legend(loc='upperleft')
ax.set_xlabel('numsteps')
ax.set_ylabel('position')
ax.grid()
我们最喜欢的秘籍
223

where关键字参数非常方便地用于突出显示图形的某些区域。其中使用
与x,ymin和ymax参数相同长度的布尔掩码,并且只填充布尔掩码
为True的区域。在下面的例子中,我们模拟一个随机漫步者,并计算人口位置
的分析平均值和标准差。群体平均值显示为黑色虚线,并且平均值的加/减一个标
准差显示为黄色填充区域。我们使用 where=X>upper_bound找到漫步者在一个
标准差边界之上的区域,并将该区域变成蓝色。
我们最喜欢的秘籍
224

透明、花式图例
有时你在绘制数据之前就知道你的数据是什么样的,并且可能知道例如右上角没有
太多数据。然后,你可以安全地创建不覆盖你的数据的图例:
ax.legend(loc='upperright')
其他时候你不知道你的数据在哪里,而 loc='best'将尝试和放置图例:
ax.legend(loc='best')
但仍然,你的图例可能会覆盖你的数据,在这些情况下,使图例框架透明非常不
错。
np.random.seed(1234)
fig,ax=plt.subplots(1)
ax.plot(np.random.randn(300),'o-',label='normaldistribution')
ax.plot(np.random.rand(300),'s-',label='uniformdistribution')
ax.set_ylim(-3,3)
ax.legend(loc='best',fancybox=True,framealpha=0.5)
ax.set_title('fancy,transparentlegends')
我们最喜欢的秘籍
225

放置文本框
当使用文本框装饰轴时,两个有用的技巧是将文本放置在轴域坐标中(请参见变换
教程),因此文本不会随着x或y轴的变化而移动。你还可以使用文本
的bbox属性,用 Patch实例包围文本- bbox关键字参数接受字典,字典的键
是补丁的属性。
np.random.seed(1234)
fig,ax=plt.subplots(1)
x=30*np.random.randn(10000)
mu=x.mean()
median=np.median(x)
sigma=x.std()
textstr='$\mu=%.2f$\n$\mathrm{median}=%.2f$\n$\sigma=%.2f$'%(m
u,median,sigma)
ax.hist(x,50)
#thesearematplotlib.patch.Patchproperties
props=dict(boxstyle='round',facecolor='wheat',alpha=0.5)
#placeatextboxinupperleftinaxescoords
ax.text(0.05,0.95,textstr,transform=ax.transAxes,fontsize=14
,
verticalalignment='top',bbox=props)
我们最喜欢的秘籍
226

我们最喜欢的秘籍
227

术语表
英文 中文
Annotation 标注
Artist 艺术家
Axes 轴域
Axis 轴/坐标轴
Bézier 贝塞尔
Coordinate 坐标
CoordinateSystem 坐标系
Figure 图形
Handle 句柄
Handler 处理器
Image 图像
Legend 图例
Line 线条
Patch 补丁
Path 路径
Pick 拾取
Subplot 子图
Text 文本
Tick 刻度
TickLabel 刻度标签
Transformation 变换
术语表
228