matplotlib-绘制精美的图表
matplotlib 是python最著名的画图库,它提供了一整套和matlab相似的命令API。十分适合交互式地进行制图。并且也能够方便地将它作为画图控件。嵌入GUI应用程序中。
它的文档相当完备,而且 Gallery页面 中有上百幅缩略图。打开之后都有源程序。因此假设你须要绘制某种类型的图,仅仅须要在这个页面中浏览/复制/粘贴一下,基本上都能搞定。
本章节作为matplotlib的入门介绍。将较为深入地挖掘几个样例,从中理解和学习matplotlib画图的一些基本概念。
高速画图
matplotlib的pyplot子库提供了和matlab类似的画图API,方便用户高速绘制2D图表。
让我们先来看一个简单的样例:
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 1000)
y = np.sin(x)
z = np.cos(x**2)
plt.figure(figsize=(8,4))
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2)
plt.plot(x,z,"b--",label="$cos(x^2)$")
plt.xlabel("Time(s)")
plt.ylabel("Volt")
plt.title("PyPlot First Example")
plt.ylim(-1.2,1.2)
plt.legend()
plt.show()
matplotlib中的高速画图的函数库能够通过例如以下语句加载:
import matplotlib.pyplot as plt
pylab模块
matplotlib还提供了名为pylab的模块。当中包含了很多numpy和pyplot中经常使用的函数,方便用户高速进行计算和画图,能够用于IPython中的高速交互式使用。
接下来调用figure创建一个画图对象。而且使它成为当前的画图对象。
plt.figure(figsize=(8,4))
也能够不创建画图对象直接调用接下来的plot函数直接画图,matplotlib会为我们自己主动创建一个画图对象。假设须要同一时候绘制多幅图表的话,能够是给figure传递一个整数參数指定图标的序号,假设所指定序号的画图对象已经存在的话。将不创建新的对象。而仅仅是让它成为当前画图对象。
通过figsize參数能够指定画图对象的宽度和高度。单位为英寸;dpi參数指定画图对象的分辨率,即每英寸多少个像素。缺省值为80。因此本例中所创建的图表窗体的宽度为8*80 = 640像素。
可是用工具栏中的保存button保存下来的png图像的大小是800*400像素。这是由于保存图表用的函数savefig使用不同的DPI配置,savefig函数也有一个dpi參数,假设不设置的话,将使用matplotlib配置文件里的配置,此配置能够通过例如以下语句进行查看,关于配置文件将在后面的章节进行介绍:
>>> import matplotlib
>>> matplotlib.rcParams["savefig.dpi"]
100
以下的两行程序通过调用plot函数在当前的画图对象中进行画图:
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2)
plt.plot(x,z,"b--",label="$cos(x^2)$")
plot函数的调用方式非常灵活。第一句将x,y数组传递给plot之后,用keyword參数指定各种属性:
- label : 给所绘制的曲线一个名字,此名字在图示(legend)中显示。
仅仅要在字符串前后加入"$"符号,matplotlib就会使用其内嵌的latex引擎绘制的数学公式。
- color : 指定曲线的颜色
- linewidth : 指定曲线的宽度
第二句直接通过第三个參数"b--"指定曲线的颜色和线型,这个參数称为格式化參数,它可以通过一些易记的符号高速指定曲线的样式。当中b表示蓝色,"--"表示线型为虚线。在IPython中输入 "plt.plot?
" 可以查看格式化字符串的具体配置。
接下来通过一系列函数设置画图对象的各个属性:
plt.xlabel("Time(s)")
plt.ylabel("Volt")
plt.title("PyPlot First Example")
plt.ylim(-1.2,1.2)
plt.legend()
- xlabel : 设置X轴的文字
- ylabel : 设置Y轴的文字
- title : 设置图表的标题
- ylim : 设置Y轴的范围
- legend : 显示图示
最后调用plt.show()显示出我们创建的全部画图对象。
配置属性
matplotlib所绘制的图的每一个组成部分都相应有一个对象。我们能够通过调用这些对象的属性设置方法set_*或者pyplot的属性设置函数setp设置其属性值。比如plot函数返回一个 matplotlib.lines.Line2D 对象的列表,以下的样例显示怎样设置Line2D对象的属性:
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> x = np.arange(0, 5, 0.1)
>>> line, = plt.plot(x, x*x) # plot返回一个列表,通过line,获取其第一个元素
>>> # 调用Line2D对象的set_*方法设置属性值
>>> line.set_antialiased(False)
>>> # 同一时候绘制sin和cos两条曲线,lines是一个有两个Line2D对象的列表
>>> lines = plt.plot(x, np.sin(x), x, np.cos(x)) #
>>> # 调用setp函数同一时候配置多个Line2D对象的多个属性值
>>> plt.setp(lines, color="r", linewidth=2.0)
这段样例中,通过调用Line2D对象line的set_antialiased方法,关闭对象的反锯齿效果。或者通过调用plt.setp函数配置多个Line2D对象的颜色和线宽属性。
相同我们能够通过调用Line2D对象的get_*方法。或者plt.getp函数获取对象的属性值:
>>> line.get_linewidth()
1.0
>>> plt.getp(lines[0], "color") # 返回color属性
'r'
>>> plt.getp(lines[1]) # 输出所有属性
alpha = 1.0
animated = False
antialiased or aa = True
axes = Axes(0.125,0.1;0.775x0.8)
... ...
注意getp函数仅仅能对一个对象进行操作,它有两种使用方法:
- 指定属性名:返回对象的指定属性的值
- 不指定属性名:打印出对象的全部属性和其值
matplotlib的整个图表为一个Figure对象,此对象在调用plt.figure函数时返回,我们也能够通过plt.gcf函数获取当前的画图对象:
>>> f = plt.gcf()
>>> plt.getp(f)
alpha = 1.0
animated = False
...
Figure对象有一个axes属性,其值为AxesSubplot对象的列表,每一个AxesSubplot对象代表图表中的一个子图。前面所绘制的图表仅仅包括一个子图。当前子图也能够通过plt.gca获得:
>>> plt.getp(f, "axes")
[<matplotlib.axes.AxesSubplot object at 0x05CDD170>]
>>> plt.gca()
<matplotlib.axes.AxesSubplot object at 0x05CDD170>
用plt.getp能够发现AxesSubplot对象有非常多属性。比如它的lines属性为此子图所包含的 Line2D 对象列表:
>>> alllines = plt.getp(plt.gca(), "lines")
>>> alllines
<a list of 3 Line2D objects>
>>> alllines[0] == line # 当中的第一条曲线就是最開始绘制的那条曲线
True
通过这样的方法我们能够非常easy地查看对象的属性和它们之间的包括关系,找到须要配置的属性。
绘制多轴图
一个画图对象(figure)能够包括多个轴(axis),在Matplotlib中用轴表示一个画图区域,能够将其理解为子图。上面的第一个样例中,画图对象仅仅包括一个轴,因此仅仅显示了一个轴(子图)。我们能够使用subplot函数高速绘制有多个轴的图表。subplot函数的调用形式例如以下:
subplot(numRows, numCols, plotNum)
subplot将整个画图区域等分为numRows行 * numCols列个子区域。然后依照从左到右,从上到下的顺序对每一个子区域进行编号。左上的子区域的编号为1。假设numRows,numCols和plotNum这三个数都小于10的话,能够把它们缩写为一个整数,比如subplot(323)和subplot(3,2,3)是同样的。subplot在plotNum指定的区域中创建一个轴对象。假设新创建的轴和之前创建的轴重叠的话。之前的轴将被删除。
以下的程序创建3行2列共6个轴。通过axisbg參数给每一个轴设置不同的背景颜色。
for idx, color in enumerate("rgbyck"):
plt.subplot(320+idx+1, axisbg=color)
plt.show()
假设希望某个轴占领整个行或者列的话,能够例如以下调用subplot:
plt.subplot(221) # 第一行的左图
plt.subplot(222) # 第一行的右图
plt.subplot(212) # 第二整行
plt.show()
当画图对象中有多个轴的时候,能够通过工具栏中的Configure Subplotsbutton。交互式地调节轴之间的间距和轴与边框之间的距离。假设希望在程序中调节的话,能够调用subplots_adjust函数,它有left, right, bottom, top, wspace, hspace等几个keyword參数。这些參数的值都是0到1之间的小数,它们是以画图区域的宽高为1进行正规化之后的坐标或者长度。
配置文件
一幅图有很多须要配置的属性,比如颜色、字体、线型等等。我们在画图时,并没有一一对这些属性进行配置,很多都直接採用了Matplotlib的缺省配置。
Matplotlib将缺省配置保存在一个文件里,通过更改这个文件,我们能够改动这些属性的缺省值。
Matplotlib 使用配置文件 matplotlibrc 时的搜索顺序例如以下:
- 当前路径 : 程序的当前路径
- 用户配置路径 : 通常为 HOME/.matplotlib/,能够通过环境变量MATPLOTLIBRC改动
- 系统配置路径 : 保存在 matplotlib的安装文件夹下的 mpl-data 下
通过以下的语句能够获取用户配置路径:
>>> import matplotlib
>>> matplotlib.get_configdir()
'C:\Documents and Settings\zhang\.matplotlib'
通过以下的语句能够获得眼下使用的配置文件的路径:
>>> import matplotlib
>>> matplotlib.matplotlib_fname()
'C:\Python26\lib\site-packages\matplotlib\mpl-data\matplotlibrc'
因为在当前路径和用户配置路径中都没有找到位置文件,因此最后使用的是系统配置路径下的配置文件。
假设你将matplotlibrc复制一份到脚本的当前文件夹下:
>>> import os
>>> os.getcwd()
'C:\zhang\doc'
复制配置文件之后再执行:
>>> matplotlib.matplotlib_fname()
'C:\zhang\doc\matplotlibrc'
假设你用文本编辑器打开此配置文件的话。你会发现它实际上是定义了一个字典。为了对众多的配置进行区分,keyword能够用点分开。
配置文件的读入能够使用 rc_params 函数,它返回一个配置字典:
>>> matplotlib.rc_params()
{'agg.path.chunksize': 0,
'axes.axisbelow': False,
'axes.edgecolor': 'k',
'axes.facecolor': 'w',
... ...
在matplotlib模块加载的时候会调用rc_params。并把得到的配置字典保存到rcParams变量中:
>>> matplotlib.rcParams
{'agg.path.chunksize': 0,
'axes.axisbelow': False,
... ...
matplotlib将使用rcParams中的配置进行画图。
用户能够直接改动此字典中的配置,所做的改变会反映到此后所绘制的图中。
比如以下的脚本所绘制的线将带有圆形的点标识符:
>>> matplotlib.rcParams["lines.marker"] = "o"
>>> import pylab
>>> pylab.plot([1,2,3])
>>> pylab.show()
为了方便配置。能够使用rc函数,以下的样例同一时候配置点标识符、线宽和颜色:
>>> matplotlib.rc("lines", marker="x", linewidth=2, color="red")
假设希望恢复到缺省的配置(matplotlib加载时从配置文件读入的配置)的话,能够调用 rcdefaults 函数。
>>> matplotlib.rcdefaults()
假设手工改动了配置文件,希望又一次从配置文件加载最新的配置的话,能够调用:
>>> matplotlib.rcParams.update( matplotlib.rc_params() )
Artist对象
matplotlib API包括有三层:
- backend_bases.FigureCanvas : 图表的绘制领域
- backend_bases.Renderer : 知道怎样在FigureCanvas上怎样画图
- artist.Artist : 知道怎样使用Renderer在FigureCanvas上画图
FigureCanvas和Renderer须要处理底层的画图操作。比如使用wxPython在界面上画图。或者使用PostScript绘制PDF。Artist则处理全部的高层结构,比如处理图表、文字和曲线等的绘制和布局。
通常我们仅仅和Artist打交道,而不须要关心底层的绘制细节。
Artists分为简单类型和容器类型两种。
简单类型的Artists为标准的画图元件,比如Line2D、 Rectangle、 Text、AxesImage 等等。而容器类型则能够包括很多简单类型的Artists,使它们组织成一个总体。比如Axis、 Axes、Figure等。
直接使用Artists创建图表的标准流程例如以下:
- 创建Figure对象
- 用Figure对象创建一个或者多个Axes或者Subplot对象
- 调用Axies等对象的方法创建各种简单类型的Artists
以下首先调用pyplot.figure辅助函数创建Figure对象,然后调用Figure对象的add_axes方法在当中创建一个Axes对象,add_axes的參数是一个形如[left, bottom, width, height]的列表,这些数值分别指定所创建的Axes对象相对于fig的位置和大小,取值范围都在0到1之间:
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
>>> ax = fig.add_axes([0.15, 0.1, 0.7, 0.3])
然后我们调用ax的plot方法画图,创建一条曲线,而且返回此曲线对象(Line2D)。
>>> line, = ax.plot([1,2,3],[1,2,1])
>>> ax.lines
[<matplotlib.lines.Line2D object at 0x0637A3D0>]
>>> line
<matplotlib.lines.Line2D object at 0x0637A3D0>
ax.lines是一个为包括ax的全部曲线的列表,兴许的ax.plot调用会往此列表中加入新的曲线。假设想删除某条曲线的话。直接从此列表中删除就可以。
Axes对象还包含很多其他的Artists对象,比如我们能够通过调用set_xlabel设置其X轴上的标题:
>>> ax.set_xlabel("time")
假设我们查看set_xlabel的源码的话,会发现它是通过调用以下的语句实现的:
self.xaxis.set_label_text(xlabel)
假设我们一直跟踪下去,会发现Axes的xaxis属性是一个XAxis对象:
>>> ax.xaxis
<matplotlib.axis.XAxis object at 0x06343230>
XAxis的label属性是一个Text对象:
>>> ax.xaxis.label
<matplotlib.text.Text object at 0x06343290>
而Text对象的_text属性为我们设置的值:
>>> ax.xaxis.label._text
'time'
这些对象都是Artists,因此也能够调用它们的属性获取函数来获得对应的属性:
>>> ax.xaxis.label.get_text()
'time'
Artist的属性
图表中的每一个元素都用一个matplotlib的Artist对象表示,而每一个Artist对象都有一大堆属性控制其显示效果。比如Figure对象和Axes对象都有patch属性作为其背景,它的值是一个Rectangle对象。
通过设置此它的一些属性能够改动Figrue图表的背景颜色或者透明度等属性,以下的样例将图表的背景颜色设置为绿色:
>>> fig = plt.figure()
>>> fig.show()
>>> fig.patch.set_color("g")
>>> fig.canvas.draw()
patch的color属性通过set_color函数进行设置。属性改动之后并不会马上反映到图表的显示上,还须要调用fig.canvas.draw()函数才可以更新显示。
以下是Artist对象都具有的一些属性:
- alpha : 透明度,值在0到1之间。0为全然透明,1为全然不透明
- animated : 布尔值,在绘制动画效果时使用
- axes : 此Artist对象所在的Axes对象。可能为None
- clip_box : 对象的裁剪框
- clip_on : 是否裁剪
- clip_path : 裁剪的路径
- contains : 推断指定点是否在对象上的函数
- figure : 所在的Figure对象,可能为None
- label : 文本标签
- picker : 控制Artist对象选取
- transform : 控制偏移旋转
- visible : 是否可见
- zorder : 控制画图顺序
Artist对象的全部属性都通过对应的 get_* 和 set_* 函数进行读写,比如以下的语句将alpha属性设置为当前值的一半:
>>> fig.set_alpha(0.5*fig.get_alpha())
假设你想用一条语句设置多个属性的话,能够使用set函数:
>>> fig.set(alpha=0.5, zorder=2)
使用前面介绍的 matplotlib.pyplot.getp 函数能够方便地输出Artist对象的全部属性名和值。
>>> plt.getp(fig.patch)
aa = True
alpha = 1.0
animated = False
antialiased or aa = True
... ...
Figure容器
如今我们知道怎样观察和改动已知的某个Artist对象的属性,接下来要解决怎样找到指定的Artist对象。前面我们介绍过Artist对象有容器类型和简单类型两种,这一节让我们来具体看看容器类型的内容。
最大的Artist容器是matplotlib.figure.Figure,它包含组成图表的全部元素。图表的背景是一个Rectangle对象,用Figure.patch属性表示。当你通过调用add_subplot或者add_axes方法往图表中加入轴(子图时)。这些子图都将加入到Figure.axes属性中,同一时候这两个方法也返回加入进axes属性的对象,注意返回值的类型有所不同。实际上AxesSubplot是Axes的子类。
>>> fig = plt.figure()
>>> ax1 = fig.add_subplot(211)
>>> ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])
>>> ax1
<matplotlib.axes.AxesSubplot object at 0x056BCA90>
>>> ax2
<matplotlib.axes.Axes object at 0x056BC910>
>>> fig.axes
[<matplotlib.axes.AxesSubplot object at 0x056BCA90>,
<matplotlib.axes.Axes object at 0x056BC910>]
为了支持pylab中的gca()等函数,Figure对象内部保存有当前轴的信息。因此不建议直接对Figure.axes属性进行列表操作,而应该使用add_subplot, add_axes, delaxes等方法进行加入和删除操作。
可是使用for循环对axes中的每一个元素进行操作是没有问题的。以下的语句打开全部子图的栅格。
>>> for ax in fig.axes: ax.grid(True)
Figure对象能够拥有自己的文字、线条以及图像等简单类型的Artist。
缺省的坐标系统为像素点。可是能够通过设置Artist对象的transform属性改动坐标系的转换方式。
最经常使用的Figure对象的坐标系是以左下角为坐标原点(0,0),右上角为坐标(1,1)。以下的程序创建并加入两条直线到fig中:
>>> from matplotlib.lines import Line2D
>>> fig = plt.figure()
>>> line1 = Line2D([0,1],[0,1], transform=fig.transFigure, figure=fig, color="r")
>>> line2 = Line2D([0,1],[1,0], transform=fig.transFigure, figure=fig, color="g")
>>> fig.lines.extend([line1, line2])
>>> fig.show()
注意为了让所创建的Line2D对象使用fig的坐标,我们将fig.TransFigure赋给Line2D对象的transform属性。为了让Line2D对象知道它是在fig对象中,我们还设置其figure属性为fig;最后还须要将创建的两个Line2D对象加入到fig.lines属性中去。
Figure对象有例如以下属性包括其他的Artist对象:
- axes : Axes对象列表
- patch : 作为背景的Rectangle对象
- images : FigureImage对象列表。用来显示图片
- legends : Legend对象列表
- lines : Line2D对象列表
- patches : patch对象列表
- texts : Text对象列表,用来显示文字
Axes容器
Axes容器是整个matplotlib库的核心。它包括了组成图表的众多Artist对象,而且有很多方法函数帮助我们创建、改动这些对象。和Figure一样,它有一个patch属性作为背景,当它是笛卡尔坐标时,patch属性是一个Rectangle对象,而当它是极坐标时,patch属性则是Circle对象。
比如以下的语句设置Axes对象的背景颜色为绿色:
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> ax.patch.set_facecolor("green")
当你调用Axes的画图方法(比如plot)。它将创建一组Line2D对象。并将全部的keyword參数传递给这些Line2D对象,并将它们加入进Axes.lines属性中。最后返回所创建的Line2D对象列表:
>>> x, y = np.random.rand(2, 100)
>>> line, = ax.plot(x, y, "-", color="blue", linewidth=2)
>>> line
<matplotlib.lines.Line2D object at 0x03007030>
>>> ax.lines
[<matplotlib.lines.Line2D object at 0x03007030>]
注意plot返回的是一个Line2D对象的列表。由于我们能够传递多组X,Y轴的数据,一次绘制多条曲线。
与plot方法类似,绘制直方图的方法bar和绘制柱状统计图的方法hist将创建一个Patch对象的列表。每一个元素实际上都是Patch的子类Rectangle,而且将所创建的Patch对象都加入进Axes.patches属性中:
>>> ax = fig.add_subplot(111)
>>> n, bins, rects = ax.hist(np.random.randn(1000), 50, facecolor="blue")
>>> rects
<a list of 50 Patch objects>
>>> rects[0]
<matplotlib.patches.Rectangle object at 0x05BC2350>
>>> ax.patches[0]
<matplotlib.patches.Rectangle object at 0x05BC2350>
一般我们不会直接对Axes.lines或者Axes.patches属性进行操作,而是调用add_line或者add_patch等方法,这些方法帮助我们完毕很多属性设置工作:
>>> fig = plt.figure() >>> ax = fig.add_subplot(111) >>> rect = matplotlib.patches.Rectangle((1,1), width=5, height=12) >>> print rect.get_axes() # rect的axes属性为空 None >>> rect.get_transform() # rect的transform属性为缺省值 BboxTransformTo(Bbox(array([[ 1., 1.], [ 6., 13.]]))) >>> ax.add_patch(rect) # 将rect加入进ax <matplotlib.patches.Rectangle object at 0x05C34E50> >>> rect.get_axes() # 于是rect的axes属性就是ax <matplotlib.axes.AxesSubplot object at 0x05C09CB0>>>> # rect的transform属性和ax的transData同样 >>> rect.get_transform() ... # 太长,省略 >>> ax.transData ... # 太长,省略>>> ax.get_xlim() # ax的X轴范围为0到1,无法显示完整的rect (0.0, 1.0) >>> ax.dataLim._get_bounds() # 数据的范围和rect的大小一致 (1.0, 1.0, 5.0, 12.0) >>> ax.autoscale_view() # 自己主动调整坐标轴范围 >>> ax.get_xlim() # 于是X轴能够完整显示rect (1.0, 6.0) >>> plt.show()
通过上面的样例我们能够看出,add_patch方法帮助我们设置了rect的axes和transform属性。
以下具体列出Axes包括各种Artist对象的属性:
- artists : Artist对象列表
- patch : 作为Axes背景的Patch对象。能够是Rectangle或者Circle
- collections : Collection对象列表
- images : AxesImage对象列表
- legends : Legend对象列表
- lines : Line2D对象列表
- patches : Patch对象列表
- texts : Text对象列表
- xaxis : XAxis对象
- yaxis : YAxis对象
以下列出Axes的创建Artist对象的方法:
Axes的方法 | 所创建的对象 | 加入进的列表 |
annotate | Annotate | texts |
bars | Rectangle | patches |
errorbar | Line2D, Rectangle | lines,patches |
fill | Polygon | patches |
hist | Rectangle | patches |
imshow | AxesImage | images |
legend | Legend | legends |
plot | Line2D | lines |
scatter | PolygonCollection | Collections |
text | Text | texts |
以下以绘制散列图(scatter)为例,验证一下:
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> t = ax.scatter(np.random.rand(20), np.random.rand(20))
>>> t # 返回值为CircleCollection对象
<matplotlib.collections.CircleCollection object at 0x06004230>
>>> ax.collections # 返回的对象已经加入进了collections列表中
[<matplotlib.collections.CircleCollection object at 0x06004230>]
>>> fig.show()
>>> t.get_sizes() # 获得Collection的点数
20
Axis容器
Axis容器包含坐标轴上的刻度线、刻度文本、坐标网格以及坐标轴标题等内容。刻度包含主刻度和副刻度,分别通过Axis.get_major_ticks和Axis.get_minor_ticks方法获得。
每一个刻度线都是一个XTick或者YTick对象,它包含实际的刻度线和刻度文本。
为了方便訪问刻度线和文本,Axis对象提供了get_ticklabels和get_ticklines方法分别直接获得刻度线和刻度文本:
>>> pl.plot([1,2,3],[4,5,6]) [<matplotlib.lines.Line2D object at 0x0AD3B670>] >>> pl.show() >>> axis = pl.gca().xaxis>>> axis.get_ticklocs() # 获得刻度的位置列表 array([ 1. , 1.5, 2. , 2.5, 3. ])>>> axis.get_ticklabels() # 获得刻度标签列表 <a list of 5 Text major ticklabel objects> >>> [x.get_text() for x in axis.get_ticklabels()] # 获得刻度的文本字符串 [u'1.0', u'1.5', u'2.0', u'2.5', u'3.0']>>> axis.get_ticklines() # 获得主刻度线列表,图的上下刻度线共10条 <a list of 10 Line2D ticklines objects>>>> axis.get_ticklines(minor=True) # 获得副刻度线列表 <a list of 0 Line2D ticklines objects>
获得刻度线或者刻度标签之后,能够设置其各种属性。以下设置刻度线为绿色粗线,文本为红色而且旋转45度:
>>> for label in axis.get_ticklabels(): ... label.set_color("red") ... label.set_rotation(45) ... label.set_fontsize(16) ...>>> for line in axis.get_ticklines(): ... line.set_color("green") ... line.set_markersize(25) ... line.set_markeredgewidth(3)
终于的结果图例如以下:
上面的样例中,获得的副刻度线列表为空,这是由于用于计算副刻度的对象缺省为NullLocator,它不产生不论什么刻度线;而计算主刻度的对象为AutoLocator,它会依据当前的缩放等配置自己主动计算刻度的位置:
>>> axis.get_minor_locator() # 计算副刻度的对象
<matplotlib.ticker.NullLocator instance at 0x0A014300>
>>> axis.get_major_locator() # 计算主刻度的对象
<matplotlib.ticker.AutoLocator instance at 0x09281B20>
我们能够使用程序为Axis对象设置不同的Locator对象,用来手工设置刻度的位置;设置Formatter对象用来控制刻度文本的显示。
以下的程序设置X轴的主刻度为pi/4,副刻度为pi/20,而且主刻度上的文本以pi为单位:
# -*- coding: utf-8 -*-
import matplotlib.pyplot as pl
from matplotlib.ticker import MultipleLocator, FuncFormatter
import numpy as np
x = np.arange(0, 4*np.pi, 0.01)
y = np.sin(x)
pl.figure(figsize=(8,4))
pl.plot(x, y)
ax = pl.gca()
def pi_formatter(x, pos):
"""
比較罗嗦地将数值转换为以pi/4为单位的刻度文本
"""
m = np.round(x / (np.pi/4))
n = 4
if m%2==0: m, n = m/2, n/2
if m%2==0: m, n = m/2, n/2
if m == 0:
return "0"
if m == 1 and n == 1:
return "$pi$"
if n == 1:
return r"$%d pi$" % m
if m == 1:
return r"$frac{pi}{%d}$" % n
return r"$frac{%d pi}{%d}$" % (m,n)
# 设置两个坐标轴的范围
pl.ylim(-1.5,1.5)
pl.xlim(0, np.max(x))
# 设置图的底边距
pl.subplots_adjust(bottom = 0.15)
pl.grid() #开启网格
# 主刻度为pi/4
ax.xaxis.set_major_locator( MultipleLocator(np.pi/4) )
# 主刻度文本用pi_formatter函数计算
ax.xaxis.set_major_formatter( FuncFormatter( pi_formatter ) )
# 副刻度为pi/20
ax.xaxis.set_minor_locator( MultipleLocator(np.pi/20) )
# 设置刻度文本的大小
for tick in ax.xaxis.get_major_ticks():
tick.label1.set_fontsize(16)
pl.show()
关于刻度的定位和文本格式的东西都在matplotlib.ticker中定义,程序中使用到例如以下两个类:
- MultipleLocator : 以指定值的整数倍为刻度放置刻度线
- FuncFormatter : 使用指定的函数计算刻度文本,他会传递给所指定的函数两个參数:刻度值和刻度序号,程序中通过比較笨的办法计算出刻度值所相应的刻度文本
此外还有非常多提前定义的Locator和Formatter类,具体内容请參考对应的API文档。