如何用python画图 高级画图的方法及软件

Python科学计算
快速绘图 & 用Python做科学计算-基础篇
使用pyplot模块绘图
matplotlib的pyplot模块提供了和MATLAB类似的绘图API,方便用户快速绘制二维图表。我们先看一个简单的例子:
用pylab库快速绘图
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() #?
程序的输出如所示。
使用pyplot模块快速将数据绘制成曲线图
?首先载入matplotlib的绘图模块pyplot,并且重命名为plt。
matplotlib还提供了一个名为pylab的模块,其中包括了许多NumPy和pyplot模块中常用的函数,方便用户快速进行计算和绘图,十分适合在IPython交互式环境中使用。本书使用下面的方式载入pylab模块:
&&& import pylab as pl
?调用figure()创建一个Figure(图表)对象,并且它将成为当前Figure对象。也可以不创建Figure对象直接调用接下来的plot()进行绘图,这时matplotlib会自动创建一个Figure对象。figsize参数指定Figure对象的宽度和高度,其单位为英寸。此外还可以用dpi参数指定Figure对象的分辨率,即每英寸所表示的像素数,这里使用缺省值80。因此本例中所创建的Figure对象的宽度为“8*80 = 640”个像素。但是在显示出绘图窗口之后,用工具栏中的保存按钮将图表保存为图像时,所保存的图像的大小是“800*400”像素。这是因为保存图像时会使用不同的dpi设置。这个设置保存在matplotlib的配置文件中,我们可以通过如下语句查看它的值:
&&& import matplotlib
&&& matplotlib.rcParams[&savefig.dpi&]
因为保存图像时的DPI设置为100,因此所保存的图像的宽度是“8*100 = 800”个像素。rcParams是一个字典,其中保存着从配置文件读入的所有配置,在调用各种绘图函数时,这些配置将会作为各种参数的缺省值。后面我们还会对matplotlib的配置文件进行详细介绍。
?创建Figure对象之后,接下来调用plot()在当前的Figure对象中绘图。实际上plot()是在Axes(子图)对象上绘图,如果当前的Figure对象中没有Axes对象,将会为之创建一个几乎充满整个图表的Axes对象,并且使此Axes对象成为当前的Axes对象。plot()的前两个参数是分别表示X、Y轴数据的对象,这里使用的是NumPy数组。使用关键字参数可以指定所绘制的曲线的各种属性:
label:给曲线指定一个标签名称,此标签将在图示中显示。如果标签字符串的前后有字符’$’,则matplotlib会使用其内嵌的LaTex引擎将其显示为数学公式。
color:指定曲线的颜色,颜色可以用英文单词,或者以’#’字符开头的三个16进制数,例如’#ff;表示红色。或者使用值在0到1范围之内的三个元素的元组表示,例如(1.0, 0.0, 0.0)也表示红色。
linewidth:指定曲线的宽度,可以不是整数,也可以使用缩写形式的参数名lw。
使用LaTex语法绘制数学公式会极大地降低图表的描绘速度。?直接通过第三个参数’b–’指定曲线的颜色和线型,它通过一些易记的符号指定曲线的样式。其中’b’表示蓝色,’–’表示线型为虚线。在IPython中输入“plt.plot?”可以查看格式化字符串以及各个参数的详细说明。
?接下来通过一系列函数设置当前Axes对象的各个属性:
xlabel、ylabel:分别设置X、Y轴的标题文字。
title:设置子图的标题。
xlim、ylim:分别设置X、Y轴的显示范围。
legend:显示图示,即图中表示每条曲线的标签(label)和样式的矩形区域。
?最后调用plt.show()显示出绘图窗口。在通常的运行情况下,show()将会阻塞程序的运行,直到用户关闭绘图窗口。然而在带“-wthread”等参数的IPython环境下,show()不会等待窗口关闭。
还可以调用plt.savefig()将当前的Figure对象保存成图像文件,图像格式由图像文件的扩展名决定。下面的程序将当前的图表保存为“test.png”,并且通过dpi参数指定图像的分辨率为120,因此输出图像的宽度为“8*120 = 960”个像素。
&&& run matplotlib_simple_plot.py
&&& plt.savefig(&test.png&, dpi=120)
如果关闭了图表窗口,则无法使用savefig()保存图像。实际上不需要调用show()显示图表,可以直接用savefig()将图表保存成图像文件。使用这种方法可以很容易编写批量输出图表的程序。savefig()的第一个参数可以是文件名,也可以是和Python的文件对象有相同调用接口的对象。例如可以将图像保存到StringIO对象中,这样就得到了一个表示图像内容的字符串。这里需要使用fmt参数指定保存的图像格式。
&&& from StringIO import StringIO
&&& buf = StringIO() # 创建一个用来保存图像内容的StringIO对象
&&& plt.savefig(buf, fmt=&png&) # 将图像以png格式保存进buf中
&&& buf.getvalue()[:20] # 显示图像内容的前20个字节
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03 '
面向对象方式绘图
matplotlib实际上是一套面向对象的绘图库,它所绘制的图表中的每个绘图元素,例如线条、文字、刻度等在内存中都有一个对象与之对应。为了方便快速绘图matplotlib通过pyplot模块提供了一套和MATLAB类似的绘图API,将众多绘图对象所构成的复杂结构隐藏在这套API内部。我们只需要调用pyplot模块所提供的函数就可以实现快速绘图以及设置图表的各种细节。pyplot模块虽然用法简单,但不适合在较大的应用程序中使用,因此本章将着重介绍如何使用matplotlib的面向对象的方式编写绘图程序。
为了将面向对象的绘图库包装成只使用函数的调用接口,pyplot模块的内部保存了当前图表以及当前子图等信息。当前的图表和子图可以使用gcf()和gca()获得,它们分别是“Get Current Figure”和“Get Current Axis”的开头字母缩写。gcf()获得的是表示图表的Figure对象,而gca()则获得的是表示子图的Axes对象。下面我们在IPython中运行上节的“matplotlib_simple_plot.py”程序,然后调用gcf()和gca()查看当前的Figure和Axes对象。
&&& run matplotlib_simple_plot.py
&&& fig = plt.gcf()
&&& axes = plt.gca()
&matplotlib.figure.Figure object at 0x04B30090&
&matplotlib.axes.AxesSubplot object at 0x04BD8E70&
在pyplot模块中,许多函数都是对当前的Figure或Axes对象进行处理,例如前面所介绍的plot()、xlabel()、savefig()等。我们可以在IPython中输入函数名并加”??”,查看这些函数的源代码了解它们是如何调用各种对象的方法进行绘图处理的。例如下面的例子查看plot()的源程序,可以看到plot()实际上会通过gca()获得当前的Axes对象ax,然后再调用它的plot()方法实现真正的绘图。请读者使用类似的方法查看pyplot模块的其它函数是如何对各种绘图对象进行包装的。
&&& plt.plot??
def plot(*args, **kwargs):
ax = gca()
ret = ax.plot(*args, **kwargs)
ax.hold(washold)
matplotlib所绘制的图表的每个组成部分都和一个对象对应,我们可以通过调用这些对象的属性设置方法set_*()或者pyplot模块的属性设置函数setp()设置它们的属性值。例如plot()返回一个元素类型为Line2D的列表,下面的例子设置Line2D对象的属性:
&&& x = np.arange(0, 5, 0.1)
&&& line = plt.plot(x, x*x)[0] # plot返回一个列表
&&& line.set_antialiased(False) # 调用Line2D对象的set_*()方法设置属性值
上面的例子中,通过调用Line2D对象的set_antialiased(False),关闭了它在图表中对应的曲线的反锯齿效果。下面的语句同时绘制正弦和余弦两条曲线,lines是一个有两个Line2D对象的列表:
&&& lines = plt.plot(x, np.sin(x), x, np.cos(x))
调用setp()可以同时配置多个对象的属性,这里我们同时设置两条曲线的颜色和线宽:
&&& plt.setp(lines, color=&r&, linewidth=2.0)
同样,可以通过调用Line2D对象的get_*(),或者plt.getp()获取对象的属性值:
&&& line.get_linewidth()
&&& 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()和setp()不同,它只能对一个对象进行操作,它有两种用法:
指定属性名:返回对象的某个属性的值
不指定属性名:输出对象的所有属性和值
下面通过getp()查看Figure对象的属性:
&&& f = plt.gcf()
&&& plt.getp(f)
alpha = 1.0
animated = False
Figure对象的axes属性是一个列表,它保存图表中的所有子图对象。下面的程序查看当前图表的axes属性,可以看出其中包含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 # 其中的第一条曲线就是最开始绘制的那条曲线
通过这种方法可以很容易查看对象的属性值以及各个对象之间的关系,找到需要配置的属性。
因为matplotlib实际上是一套面向对象的绘图库,因此也可以直接获取对象的属性,例如:
&&& f.axes
[&matplotlib.axes.AxesSubplot object at 0x05CDD170&]
&&& f.axes[0].lines
&a list of 3 Line2D objects&
绘制多子图
一个Figure对象可以包含多个子图(Axes),在matplotlib中用Axes对象表示一个绘图区域,在本书中称之为子图。在前面的例子中,Figure对象只包括一个子图。我们可以使用subplot()快速绘制包含多个子图的图表,它的调用形式如下:
subplot(numRows, numCols, plotNum)
图表的整个绘图区域被等分为numRows行和numCols列,然后按照从左到右、从上到下的顺序对每个区域进行编号,左上区域的编号为1。plotNum参数指定所创建Axes对象所在的区域。如果numRows、numCols和plotNum三个参数都小于10,则可以把它们缩写成一个整数,例如subplot(323)和subplot(3,2,3)的含义相同。如果新创建的子图和之前创建的子图区域有重叠的部分,则之前的子图将被删除。
下面的程序创建如所示的3行2列共6个子图,并通过axisbg参数给每个子图设置不同的背景颜色。
for idx, color in enumerate(&rgbyck&):
plt.subplot(321+idx, axisbg=color)
plt.show()
用subplot()在当前的Figure对象中创建6个子图
如果希望某个子图占据整行或者整列,可以如下调用subplot():
plt.subplot(221) # 第一行的左图
plt.subplot(222) # 第一行的右图
plt.subplot(212) # 第二整行
plt.show()
程序的输出如所示。
将Figure分为三个子图
在绘图窗口的工具栏中,有一个名为“Configure Subplots”的按钮,点击它弹出调节子图间距和子图与图表边框距离的对话框。也可以在程序中调用subplots_adjust()调节这些参数,它有left、right、bottom、top、wspace和hspace等六个参数,这些参数与对话框中的各个控件对应。参数的取值范围为0到1,它们是以图表绘图区域的宽和高进行正规化之后的坐标或者长度。
subplot()返回它所创建的Axes对象,我们可以将它用变量保存起来,然后用sca()交替让它们成为当前Axes对象,并调用plot()在其中绘图。如果需要同时绘制多幅图表,可以给figure()传递一个整数参数指定Figure对象的序号,如果序号所指定的Figure对象已经存在,将不创建新的对象,而只是让它成为当前的Figure对象。下面的程序演示了依次在不同图表的不同子图中绘制曲线。
同时在多幅图表、多个子图中进行绘图
import numpy as np
import matplotlib.pyplot as plt
plt.figure(1) # 创建图表1
plt.figure(2) # 创建图表2
ax1 = plt.subplot(211) # 在图表2中创建子图1
ax2 = plt.subplot(212) # 在图表2中创建子图2
x = np.linspace(0, 3, 100)
for i in xrange(5):
plt.figure(1)
#? # 选择图表1
plt.plot(x, np.exp(i*x/3))
plt.sca(ax1)
#? # 选择图表2的子图1
plt.plot(x, np.sin(i*x))
plt.sca(ax2)
# 选择图表2的子图2
plt.plot(x, np.cos(i*x))
plt.show()
首先通过figure()创建了两个图表,它们的序号分别为1和2。然后在图表2中创建了上下并排的两个子图,并用变量ax1和ax2保存。
在循环中,?先调用figure(1)让图表1成为当前图表,并在其中绘图。?然后调用sca(ax1)和sca(ax2)分别让子图ax1和ax2成为当前子图,并在其中绘图。当它们成为当前子图时,包含它们的图表2也自动成为当前图表,因此不需要调用figure(2)。这样依次在图表1和图表2的两个子图之间切换,逐步在其中添加新的曲线。其效果如所示。
同时在多幅图表、多个子图中进行绘图
绘制一幅图需要对许多对象的属性进行配置,例如颜色、字体、线型等等。我们在绘图时,并没有逐一对这些属性进行配置,许多都直接采用了matplotlib的缺省配置。matplotlib将这些缺省配置保存在一个名为“matplotlibrc”的配置文件中,通过修改配置文件,我们可以修改图表的缺省样式。
在matplotlib中可以使用多个“matplotlibrc”配置文件,它们的搜索顺序如下,顺序靠前的配置文件将会被优先采用。
当前路径:程序的当前路径。
用户配置路径:通常在用户文件夹的“.matplotlib”目录下,可以通过环境变量MATPLOTLIBRC修改它的位置。
系统配置路径:保存在matplotlib的安装目录下的mpl-data中。
通过下面的语句可以获取用户配置路径:
&&& import matplotlib
&&& matplotlib.get_configdir()
'C:\\Documents and Settings\\用户名\\.matplotlib'
通过下面的语句可以获得目前使用的配置文件的路径:
&&& import matplotlib
&&& matplotlib.matplotlib_fname()
'C:\\Python26\\lib\\site-packages\\matplotlib\\mpl-data\\matplotlibrc'
由于在当前路径和用户配置路径中都没有找到配置文件,因此最后使用的是系统配置路径下的配置文件。如果读者将matplotlibrc复制一份到脚本的当前目录(例如,c:\zhang\doc)下:
&&& import os
&&& os.getcwd()
'C:\\zhang\\doc'
复制配置文件之后再查看配置文件的路径,就会发现它变为了当前目录下的配置文件:
&&& matplotlib.matplotlib_fname()
'C:\\zhang\\doc\\matplotlibrc'
如果读者使用文本编辑器打开此配置文件,就会发现它实际上是一个字典。为了对众多的配置进行区分,字典的键根据配置的种类,用“.”分为多段。
配置文件的读入可以使用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&
&&& plt.plot([1,2,3,2])
&&& plt.show()
为了方便对配置字典进行设置,可以使用rc()。下面的例子同时配置点标识符、线宽和颜色:
&&& matplotlib.rc(&lines&, marker=&x&, linewidth=2, color=&red&)
如果希望恢复到缺省的配置(matplotlib载入时从配置文件读入的配置),可以调用rcdefaults()。
&&& matplotlib.rcdefaults()
如果手工修改了配置文件,希望重新从配置文件载入最新的配置,可以调用:
&&& matplotlib.rcParams.update( matplotlib.rc_params() )
通过pyplot模块也可以使用rcParams、rc和rcdefaults。
在图表中显示中文
matplotlib的缺省配置文件中所使用的字体无法正确显示中文。为了让图表能正确显示中文,可以有几种解决方案。
在程序中直接指定字体。
在程序开头修改配置字典rcParams。
修改配置文件。
在matplotlib中可以通过字体名指定字体,而每个字体名都与一个字体文件相对应。通过下面的程序可以获得所有可用的字体列表:
&&& from matplotlib.font_manager import fontManager
&&& fontManager.ttflist
[&Font 'cmex10' (cmex10.ttf) normal normal 400 normal&,
&Font 'Bitstream Vera Sans Mono' (VeraMoBd.ttf) normal normal 700 normal&,
fontManager.ttflist是matplotlib的系统字体索引列表。其中的每个元素都是表示字体的Font对象。例如由第一个Font对象可知,字体名”cmex10”与字体文件“cmex10.ttf”相对应。下面的语句获得字体文件的全路径和字体名:
&&& fontManager.ttflist[0].name
'cmex10'
&&& fontManager.ttflist[0].fname
'C:\\Python26\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\ttf\\cmex10.ttf'
由字体文件的路径可知’cmex10’是matplotlib自带的字体。下面的程序利用字体索引列表中的字体显示中文文字,其效果如所示。
显示所有的中文字体
from matplotlib.font_manager import fontManager
import matplotlib.pyplot as plt
import os.path
fig = plt.figure(figsize=(12,6))
ax = fig.add_subplot(111)
plt.subplots_adjust(0, 0, 1, 1, 0, 0)
plt.xticks([])
plt.yticks([])
x, y = 0.05, 0.08
fonts = [font.name for font in fontManager.ttflist if
os.path.exists(font.fname) and os.stat(font.fname).st_size&1e6] #?
font = set(fonts)
dy = (1.0-y)/(len(fonts)/4 + (len(fonts)%4!=0))
for font in fonts:
t = ax.text(x, y, u&中文字体&, {'fontname':font, 'fontsize':14}, transform=ax.transAxes) #?
ax.text(x, y-dy/2, font, transform=ax.transAxes)
if x &= 1.0:
plt.show()
显示系统中的所有中文字体
?利用os模块中的stat()获取字体文件的大小,并保留字体索引列表中所有大于1M字节的字体文件。由于中文字体文件通常都很大,因此使用这种方法可以粗略地找出所有的中文字体文件。
?调用子图对象的text()在其中添加文字,注意文字必须是Unicode字符串。通过一个描述字体的字典指定文字的字体:’fontname’键所对应的值就是字体名。
由于matplotlib只搜索TTF字体文件,因此无法通过上述方法使用Windows的Fonts目录下的许多复合字体文件(.ttc)。可以直接创建使用字体文件的FontProperties对象,并使用此对象指定图表中的各种文字的字体。下面是一个例子:
使用TTC字体文件
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt
import numpy as np
font = FontProperties(fname=r&c:\windows\fonts\simsun.ttc&, size=14) #?
t = np.linspace(0, 10, 1000)
y = np.sin(t)
plt.plot(t, y)
plt.xlabel(u&时间&, fontproperties=font) #?
plt.ylabel(u&振幅&, fontproperties=font)
plt.title(u&正弦波&, fontproperties=font)
plt.show()
?创建一个描述字体属性的FontProperties对象,并设置其fname属性为字体文件的绝对路径。?通过fontproperties参数将FontProperties对象传递给显示文字的函数。
还可以通过字体工具将TTC字体文件分解为多个TTF字体文件,并将其复制到系统的字体文件夹中。由于为了缩短启动时间,matplotlib不会每次启动时都重新扫描所有的字体文件并创建字体索引列表,因此在复制完字体文件之后,需要运行下面的语句以重新创建字体索引列表:
&&& from matplotlib.font_manager import _rebuild
&&& _rebuild()
还可以直接修改配置字典,设置缺省字体,这样就不需要在每次绘制文字时设置字体了。例如:
&&& plt.rcParams[&font.family&] = &SimHei&
&&& plt.plot([1,2,3])
&&& plt.xlabel(0.5,0.5,u&中文字体&)
或者修改上节介绍的配置文件,修改其中的“font.family”配置为:
font.family : SimHei
注意“SimHei”是字体名,请读者运行“matplotlib_fonts.py”查看系统中所有可用的中文字体名。
本站点由提供动力使用python中的matplotlib进行绘图分析数据 - 推酷
使用python中的matplotlib进行绘图分析数据
&是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。
它的文档相当完备,并且
&中有上百幅缩略图,打开之后都有源程序。因此如果你需要绘制某种类型的图,只需要在这个页面中浏览/复制/粘贴一下,基本上都能搞定。
matplotlib的pyplot子库提供了和matlab类似的绘图API,方便用户快速绘制2D图表。例子:
# coding=gbk
Created on Jul 12, 2014
python 科学计算学习:numpy快速处理数据测试
@author: 皮皮
import string
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
file = open(&E:\machine_learning\datasets\housing_data\housing_data_ages.txt&, 'r')
linesList = file.readlines()
print(linesList)
linesList = [line.strip().split(&,&) for line in linesList]
file.close()
print(&linesList:&)
print(linesList)
years = [string.atof(x[0]) for x in linesList]
years = [x[0] for x in linesList]
print(years)
price = [x[1] for x in linesList]
print(price)
plt.plot(years, price, 'b*')#,label=&$cos(x^2)$&)
plt.plot(years, price, 'r')
plt.xlabel(&years(+2000)&)
plt.ylabel(&housing average price(*2000 yuan)&)
plt.ylim(0, 15)
plt.title('line_regression & gradient decrease')
plt.legend()
plt.show()
matplotlib中的快速绘图的函数库可以通过如下语句载入:
import matplotlib.pyplot as plt
matplotlib还提供了名为pylab的模块,其中包括了许多numpy和pyplot中常用的函数,方便用户快速进行计算和绘图,可以用于IPython中的快速交互式使用。
接下来调用figure创建一个绘图对象,并且使它成为当前的绘图对象。
plt.figure(figsize=(8,4))
也可以不创建绘图对象直接调用接下来的plot函数直接绘图,matplotlib会为我们自动创建一个绘图对象。如果需要同时绘制多幅图表的话,可以是给figure传递一个整数参数指定图标的序号,如果所指定序号的绘图对象已经存在的话,将不创建新的对象,而只是让它成为当前绘图对象。
通过figsize参数可以指定绘图对象的宽度和高度,单位为英寸;dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80。因此本例中所创建的图表窗口的宽度为8*80 = 640像素。
但是用工具栏中的保存按钮保存下来的png图像的大小是800*400像素。这是因为保存图表用的函数savefig使用不同的DPI配置,savefig函数也有一个dpi参数,如果不设置的话,将使用matplotlib配置文件中的配置,此配置可以通过如下语句进行查看:
&&& import matplotlib
&&& matplotlib.rcParams[&savefig.dpi&]
下面的两行程序通过调用plot函数在当前的绘图对象中进行绘图:
plt.plot(years, price, 'b*')#,label=&$cos(x^2)$&)
plt.plot(years, price, 'r')
plot函数的调用方式很灵活,第一句将x,y数组传递给plot之后,用关键字参数指定各种属性:
: 给所绘制的曲线一个名字,此名字在图示(legend)中显示。只要在字符串前后添加&$&符号,matplotlib就会使用其内嵌的latex引擎绘制的数学公式。
color &: 指定曲线的颜色
linewidth &: 指定曲线的宽度
第二句直接通过第三个参数&b--&指定曲线的颜色和线型,这个参数称为格式化参数,它能够通过一些易记的符号快速指定曲线的样式。其中b表示蓝色,&--&表示线型为虚线。
在IPython中输入 &plt.plot?& 可以查看格式化字符串的详细配置。
接下来通过一系列函数设置绘图对象的各个属性:
plt.xlabel(&years(+2000)&)
plt.ylabel(&housing average price(*2000 yuan)&)
plt.ylim(0, 15)
plt.title('line_regression & gradient decrease')
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()
&&& plt.getp(lines[0], &color&) # 返回color属性
&&& 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 # 其中的第一条曲线就是最开始绘制的那条曲线
通过这种方法我们可以很容易地查看对象的属性和它们之间的包含关系,找到需要配置的属性。
5.2 绘制多轴图
一个绘图对象(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()
图5.2 &用subplot函数将Figure分为六个子图区域
如果希望某个轴占据整个行或者列的话,可以如下调用subplot:
plt.subplot(221) # 第一行的左图
plt.subplot(222) # 第一行的右图
plt.subplot(212) # 第二整行
plt.show()
图5.3 &将Figure分为三个子图区域
当绘图对象中有多个轴的时候,可以通过工具栏中的Configure Subplots按钮,交互式地调节轴之间的间距和轴与边框之间的距离。如果希望在程序中调节的话,可以调用subplots_adjust函数,它有left, right, bottom, top, wspace, hspace等几个关键字参数,这些参数的值都是0到1之间的小数,它们是以绘图区域的宽高为1进行正规化之后的坐标或者长度。
5.3 配置文件
一幅图有许多需要配置的属性,例如颜色、字体、线型等等。我们在绘图时,并没有一一对这些属性进行配置,许多都直接采用了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'
如果你用文本编辑器打开此配置文件的话,你会发现它实际上是定义了一个字典。为了对众多的配置进行区分,关键字可以用点分开。
配置文件的读入可以使用 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() )
5.4 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 0x&]
&matplotlib.lines.Line2D object at 0x&
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 0x&
XAxis的label属性是一个Text对象:
&&& ax.xaxis.label
&matplotlib.text.Text object at 0x&
而Text对象的_text属性为我们设置的值:
&&& ax.xaxis.label._text
这些对象都是Artists,因此也可以调用它们的属性获取函数来获得相应的属性:
&&& ax.xaxis.label.get_text()
5.4.1 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)
alpha = 1.0
animated = False
antialiased or aa = True
5.4.2 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])
&matplotlib.axes.AxesSubplot object at 0x056BCA90&
&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()
图5.4 &在Figure对象中手工绘制直线
注意为了让所创建的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对象列表,用来显示文字
5.4.3 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对象,并将所有的关键字参数传递给这些Line2D对象,并将它们添加进Axes.lines属性中,最后返回所创建的Line2D对象列表:
&&& x, y = np.random.rand(2, 100)
&&& line, = ax.plot(x, y, &-&, color=&blue&, linewidth=2)
&matplotlib.lines.Line2D object at 0x&
&&& ax.lines
[&matplotlib.lines.Line2D object at 0x&]
注意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&)
&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属性为空
&&& rect.get_transform() # rect的transform属性为缺省值
BboxTransformTo(Bbox(array([[
&&& 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的方法
所创建的对象
添加进的列表
Line2D, Rectangle
lines,patches
PolygonCollection
Collections
下面以绘制散列图(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 0x&
&&& ax.collections # 返回的对象已经添加进了collections列表中
[&matplotlib.collections.CircleCollection object at 0x&]
&&& fig.show()
&&& t.get_sizes() # 获得Collection的点数
图5.5 &用scatter函数绘制散列图
5.4.4 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. ,
&&& 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)
最终的结果图如下:
图5.6 &手工配置X轴的刻度线和刻度文本的样式
上面的例子中,获得的副刻度线列表为空,这是因为用于计算副刻度的对象缺省为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))
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)
关于刻度的定位和文本格式的东西都在matplotlib.ticker中定义,程序中使用到如下两个类:
MultipleLocator &: 以指定值的整数倍为刻度放置刻度线
FuncFormatter &: 使用指定的函数计算刻度文本,他会传递给所指定的函数两个参数:刻度值和刻度序号,程序中通过比较笨的办法计算出刻度值所对应的刻度文本
此外还有很多预定义的Locator和Formatter类,详细内容请参考相应的API文档。
图5.7 &手工配置X轴的刻度线的位置和文本,并开启副刻度
已发表评论数()
&&登&&&录&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见

我要回帖

更多关于 python 读取数据画图 的文章

 

随机推荐