pyplot简介
pyplot是一个函数集合,能够让matplotlib像matlib一样工作,每一个函数都会对一个figure做出一些改变,例如,创建一个figure,在一个figure里创建一个plotting area,在plotting area里画一些线,在plot里加一些标签等
在pyplot函数调用之间会保留着各种状态,比如当前figure和plotting area和当前的axes(这里的axes是指figure中axes部分,不是指数学上的axis的复数)
pyplot API没有面像对象API灵活,这里能看到的大部函数都是从一个Axes对象的方法,建议看文档中的例子了解它是怎么工作的
用pyplot快速创建一张图
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()
为什么x轴是0-3,y轴是1-4,如果你给plot传入一个数组,plot会假设是一个y值的序列,然后自动创建相应的x值,因为python从0开始,默认的x向量与y同样长度,则x为[0,1,2,3]
plot是一个万能命令,它可以任意数里的参数,例如,画一个x-y二维图像,可以这样用命令
plt.plot([1,2,3,4],[1,4,9,16])
规定plot的形式
对于每个成对的x,y,还有一个可选的第三个参数,用来指定画线的颜色和类型,格式化的字母符号借鉴于matlab,你能把颜色符号与线类型连在一起,默认的格式化符号是'b-',就是蓝色的实线,如果你想画一个红色图点,可以
plt.plot([1,2,3,4],[1,4,9,16],'ro')
plt.axis([0,6,0,20])
plt.show()
plot文档里有所有的格式化参数,例子中axis()使用一个list [xmin,xmax,ymin,ymax]来指定可见范围
如果matplotlib只能用lists,那对于数字处理就没什么用了.一般来讲,你可以用numpy.array,实际上,所有序列都被内部转换成numpy.array,下面的例子用不同的形式画了一些线
import numpy as np
#evenly sampled time at 200ms intervals
t = np.arange(0., 5., 0.2)
#red dashes, blue squares and green triangles
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()
使用关键字plotting
有一些实例,是通过字符串访问变量里的数据,例numpy.recarray,pandas.DataFrame
matplotlib可以让你提供一些带有关键字字典的对象,如果是这样的对象,plot可以把字符串和变量关联起来
data = {'a': np.arange(50),
'c': np.random.randint(0, 50, 50),
'd': np.random.randn(50)}
data['b'] = data['a'] + 10 * np.random.randn(50)
data['d'] = np.abs(data['d']) * 100
plt.scatter('a', 'b', c='c', s='d', data=data)
plt.xlabel('entry a')
plt.ylabel('entry b')
plt.show()
使用分类变量做图
也可以使用分类变量做图,matlibplot有很多函数可以传入分类变量
names = ['group_a', 'group_b', 'group_c']
values = [1, 10, 100]
plt.figure(1, figsize=(9, 3))
plt.subplot(131)
plt.bar(names, values)
plt.subplot(132)
plt.scatter(names, values)
plt.subplot(133)
plt.plot(names, values)
plt.suptitle('Categorical Plotting')
plt.show()
控制线属性
线有很多属性,如线宽,样式,反锯齿,有很多方式设置线的属性
- 用关键字参数设置
plt.plot(x,y,linewidth=2.0)
- 用line2D实例的setter方法,plot会返回一列Line2D对像,例,line1,line2=plot(x1,y1,x2,y2),下面我们假设只有一条线,也就是返回的列表长度为1,我们元组拆包得到列表的第一个元素
line, = plt.plot(x, y, '-')
line.set_antialiased(False) # turn off antialising
- 用setp命令,下面这个例子用一个matlab命令设置一条线的多个属性,setp可以传入一个或一列对象,可以使用关键字设置属性
lines = plt.plot(x1, y1, x2, y2)
#use keyword args
plt.setp(lines, color='r', linewidth=2.0)
#or MATLAB style string value pairs
plt.setp(lines, 'color', 'r', 'linewidth', 2.0)
Property | Value Type |
---|---|
alpha | float |
color or c | 任何matlibplot颜色 |
获取可设置属性的列表,调用setp函数
In [69]: lines = plt.plot([1, 2, 3])
In [70]: plt.setp(lines)
alpha: float
animated: [True | False]
antialiased or aa: [True | False]
...snip
使用多个figure和axes
Matlab和pyplot,有一个当前figure和当前axes的概念,所有的plot命令都会作用在当前axes上,函数gca()返回当前axes,gcf()返回当前figure
通常,你不用担心这个,因为都在内部处理了这些问题,下面是一个创建两个subplot的脚本
def f(t):
return np.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,会默认创建subplot(111),subplot指定行数,列数,plot序号,plot序号的范围是1到行数乘以列数.如果行列数相乘小于10,参数里的逗号是可选的,因为subplot(211)默认是指subplot(2,1,1)
你可以创建任何数量的subplot和axes,如果你想用axes()命令手动指定axes位置(例如不是一个矩形),你可以用axes([left,bottom,width,height]),这里所有数都是小数(0 to1)
可以多次用一个增长的数当参数调用figure()创建多个figures,当然,每个figure都包括多个subplot和axes
import matplotlib.pyplot as plt
plt.figure(1) # the first figure
plt.subplot(211) # the first subplot in the first figure
plt.plot([1, 2, 3])
plt.subplot(212) # the second subplot in the first figure
plt.plot([4, 5, 6])
plt.figure(2) # a second figure
plt.plot([4, 5, 6]) # creates a subplot(111) by default
plt.figure(1) # figure 1 current; subplot(212) still current
plt.subplot(211) # make subplot(211) in figure1 current
plt.title('Easy as 1, 2, 3') # subplot 211 title
clf()可以清除当前figure,cla()可以清除当前axes,如果你觉得内部状态不好用,你可以用弱状态的面向对象API来代替它
如果你创建了多个figure,你需要注意一件事,figure是在调用close()的时候内存才被释放,删除所有figure,或用窗口管理器关闭窗口是不行的,因为pyplot在close()调用之前会有很多内部引用
使用text
text()命令可以在任何位置填加文本,xlabel,ylabel和title可以在指定的地方填加文本
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
#the histogram of the data
n, bins, patches = plt.hist(x, 50, density=1, facecolor='g', alpha=0.75)
plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
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实例,和线段一样,你可以在函数里或者setp里用关键字参数自定义属性
t = plt.xlabel('my data', fontsize=14, color='red')
文本里用数学表达式
matplotlib里文本里可以用Tex方程表达式,例如,你想写sigma=15,你可以用Tex表达式,然后用$括起来
plt.title(r'$\sigma_i=15$')
前面的r很重要,它意味着\是字符串,不要当成python转义符,matplotlib有一个内置的Tex解析器和布局引擎,和自己的数字字体,也就是说可以在跨平台的时候不用安装Tex,如果安装了LaTex和dvipng,也可以用来做输出
注释文本
text()可以用在axes的任何位置,一个用法就是用来注释,annotate()可以很容易的提供帮助功能,有两个坐标点要考虑,xy和xytext,都是元组形式
ax = plt.subplot(111)
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)
plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05),
)
plt.ylim(-2, 2)
plt.show()
对数和其他非线性的axes
matplotlib不仅提供线性坐标轴刻度,而且还提供对数和分对数刻度,这种刻度对跨度很大的数据很有用,改变刻度比例很简单:
plt.xscale('log')
y轴不同刻度的例子
from matplotlib.ticker import NullFormatter # useful for `logit` scale
# Fixing random state for reproducibility
np.random.seed(19680801)
# make up some data in the interval ]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 with various axes scales
plt.figure(1)
# linear
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)
# log
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)
# symmetric log
plt.subplot(223)
plt.plot(x, y - y.mean())
plt.yscale('symlog', linthreshy=0.01)
plt.title('symlog')
plt.grid(True)
# logit
plt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
# Format the minor tick labels of the y-axis into empty strings with
# `NullFormatter`, to avoid cumbering the axis with too many labels.
plt.gca().yaxis.set_minor_formatter(NullFormatter())
# Adjust the subplot layout, because the logit one may take more space
# than usual, due to y-tick labels like "1 - 10^{-3}"
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
wspace=0.35)
plt.show()
你也可以填加自己的刻度比例