本文主要介绍pyplot的应用接口 matplotlib.pyplot是一个函数集,可以让matplotlib像MATLAB一样工作,每一个pyplot函数都会让一个Figure对象产生一些变化,如创建一个画布(Figure),在Figrue上创建一个绘图区,在绘图区中画一些线条,给图形加标签等。
在matplotlib.pyplot中,对图形状态的保存贯穿函数的调用过程,所以它可以跟踪一些东西,如当前的Figure和绘图区域,绘图函数指向当前的axes(坐标系)——注意,这里的axes和大多数文档里提到的,指的是图形的坐标系部分,而不是数学意义上的多个坐标轴。
注意:隐式调用的bylot API通常比显式调用的API更简单一些。大多数你这里调用的方法也可以用Axes对象来调用。我们建议多浏览教程和示例来加深对它们如何工作的理解。
使用bylot生成可视化效果非常快:
In [1]:
importmatplotlib.pyplotaspltplt.plot([1,2,3,4])plt.ylabel('some numbers')plt.show()
您也许会好奇,为什么x轴的取值范围是0到3,而y轴的取值范围是1到4。如果您提供了一个简单的list列表或array数组给plot,matplotlib就会认定那是一列y值,并会为您自动生成一系列的x值。由于Python的ranges从0开始,默认的x矢量值就会从0开始且与y具有相同的长度,也就是说,x的值是[0,1,2,3]。 plot量一个多用图函数,并且可以带着任意数量的参数。比如,要想同时画上x和y,您可以:
In [2]:
plt.plot([1,2,3,4],[1,4,9,16])
Out[2]:
[
对于每一个x,y坐标参数,有第三个可选参数,即格式化字符,定义了图的颜色和线形,字符中的字母和符号来自于MATLAB,您可以联合颜色字符串和线形字符串,默认的字符串是“b-”,是一个蓝色的实线。如果您想让上图输出一个红点图,需要输入:
In [3]:
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]的参数列表,并在轴上显示出来。
如果matplotlib仅限于处理列表 ,那它对数据处理来说,真的很没用,通常,您会使用numpy数组,事实上,所有的列表在内部都转化成了numpy的数组了。下面的例子在用一个函数用不同的风络绘制了多条线。
In [4]:
importnumpyasnpt=np.arange(0.,5.,0.2)plt.plot(t,t,'r--',t,t**2,'bs',t,t**3,'g^')plt.show()
在一些特殊的例子里,有一些数据可以接收特殊的字符串做为变量。比如numpy.recarray或pandas.DataFrame。Matplotlib允许您提供这样一个对象:使用data关键字参数。如果您提供了,然后您就可以用字符串生成相应的图象。
In [5]:
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'])*100plt.scatter('a','b',c='c',s='d',data=data)plt.xlabel('entry a')plt.ylabel('entry b')plt.show()
Matplotlib的很多函数允许您直接使用分类变量,如:
In [6]:
names=['group_a','group_b','group_c']values=[1,10,100]plt.figure(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()
线型有很多您可以控制的参数:线宽、点划、锯齿等,详细内容可以查matplotlib.lines.line2D,有几种方式可以设置线型。
使用关键字参数: plt.plot(x,y,linewidth=2.0)
使用对象实例的设置方法。plot返回一个Line2D的对象列表,比如,line1,line2 = plot(x1,y1,x2,y2)。在下面的代码中,我们假设我们只有一条线,我们使用tuple来解包line,来获得列表的元素。
line,=plt.plot(x,y,'-')line.set_antialiased(False)#关闭锯齿
使用 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的property。 |Property|值的类型| |-----|-----| |alpha|float| |animated|[True/False]| |antialiased/aa|[True/False]| |clip_box|一个matplotlib.transform.Bbox对象| |clip_on|[True/False]| |clip_path|一个Path实例和一个Transform实例,一个色块| |color/c|任何matplotlib的color对象| |contains|命中测试功能| |dash_capstyle|['butt'/'round'/'projecting']| |dash_joinstyle|['miter'/'round'/'bevel']| |dashes|sequence of on/off ink in points| |data|(np.arry xdata,np.array ydata)| |figure|一个matplotlib.figure.Figure实例| |label|任意字符串| |linestyle/ls|[ '-' / '--' / '-.' / ':' / 'steps' / ...]| |linewidth/lw|float value in points| |marker|[ '+' / ',' / '.' / '1' / '2' / '3' / '4' ]| |markeredgecolor/mec|任意matplotlib颜色| |markeredgewidth/mew|float value in points| |markerfacecolor/mfc|任意matplotlib颜色| |markersize/ms|float| |markevery|[ None / integer / (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|任意数值|
要获取可设置特色的列表,请使用一行或多行参数来调用setp函数。
In [16]:
lines=plt.plot([1,2,3])plt.setp(lines)
agg_filter: a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array and two offsets from the bottom left corner of the image
alpha: scalar or None
animated: bool
antialiased or aa: bool
clip_box: `.Bbox`
clip_on: bool
clip_path: Patch or (Path, Transform) or None
color or c: color
dash_capstyle: `.CapStyle` or {'butt', 'projecting', 'round'}
dash_joinstyle: `.JoinStyle` or {'miter', 'round', 'bevel'}
dashes: sequence of floats (on/off ink in points) or (None, None)
data: (2, N) array or two 1D arrays
drawstyle or ds: {'default', 'steps', 'steps-pre', 'steps-mid', 'steps-post'}, default: 'default'
figure: `.Figure`
fillstyle: {'full', 'left', 'right', 'bottom', 'top', 'none'}
gid: str
in_layout: bool
label: object
linestyle or ls: {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
linewidth or lw: float
marker: marker style string, `~.path.Path` or `~.markers.MarkerStyle`
markeredgecolor or mec: color
markeredgewidth or mew: float
markerfacecolor or mfc: color
markerfacecoloralt or mfcalt: color
markersize or ms: float
markevery: None or int or (int, int) or slice or list[int] or float or (float, float) or list[bool]
path_effects: `.AbstractPathEffect`
picker: float or callable[[Artist, Event], tuple[bool, dict]]
pickradius: float
rasterized: bool
sketch_params: (scale: float, length: float, randomness: float)
snap: bool or None
solid_capstyle: `.CapStyle` or {'butt', 'projecting', 'round'}
solid_joinstyle: `.JoinStyle` or {'miter', 'round', 'bevel'}
transform: `.Transform`
url: str
visible: bool
xdata: 1D array
ydata: 1D array
zorder: float
您可以使用对齐参数horizontalalignment,verticalalignment,multialignment布局文本。horizontalalignment控制着x位置参数是指文本边界的左侧、中间还是右侧,vertialignment控制文本的y位置参数是文本边界框的底部、中心或顶部,multialignment仅用有换行分隔符的字符串,控制不同行的左对齐,居中对齐和右对齐。下面是一个使用text()命令显示对齐情况的示例,代码中使用的transform=ax.transAxes表示坐标是相对于坐标系边界框给出的,(0,0)是轴的左下角,(1,1)是右上角。
In [21]:
importmatplotlib.pyplotaspltimportmatplotlib.patchesaspatchesleft,width=.25,.5bottom,height=.25,.5right=bottom+heighttop=bottom+heightfig=plt.figure()ax=fig.add_axes([0,0,1,1])p=patches.Rectangle((left,bottom),width,height,fill=False,transform=ax.transAxes,clip_on=False)ax.add_patch(p)ax.text(left,bottom,'left top',horizontalalignment='left',verticalalignment='top',transform=ax.transAxes)ax.text(left,bottom,'left bottom',horizontalalignment='left',verticalalignment='bottom',transform=ax.transAxes)ax.text(right,top,'right bottom',horizontalalignment='right',verticalalignment='bottom',transform=ax.transAxes)ax.text(right,top,'right top',horizontalalignment='right',verticalalignment='top',transform=ax.transAxes)ax.text(right,bottom,'center top',horizontalalignment='center',verticalalignment='top',transform=ax.transAxes)ax.text(left,0.5*(bottom+top),'right center',horizontalalignment='right',verticalalignment='center',rotation='vertical',transform=ax.transAxes)ax.text(left,0.5*(bottom+top),'left center',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\nwith newlines',horizontalalignment='center',verticalalignment='center',rotation=45,transform=ax.transAxes)# ax.set_axis_off()plt.show()
MATLAB,以及pyplot,是有一个当前画板和当前坐标系的概念。所有的画图方法支持当前的坐标系。方法gca返回当前坐标系(一个matplotlib.axes.Axes实例),gcf方法返回当前画板(一个matplotlib.figure.Figure实例)。正常来说,你不必关心这个事儿,因为那是在场景后台需要关心的。下面是一个创建两个子图的脚本。
In [8]:
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()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对象将会在不存在的情况下被创建,就像是Axes被创建时一样(等同于显式创建subplot())。调用subplot时参数有行数,列数,图号,图号多1开始排,总量是行数列数。当行数列数<10时,逗号可以省略。所以subplot(211)也就是subplot(2,1,1)。
您可以创建任意数量的子图和坐标系,如果您想要手动放置一个Axes,使用axes([left,bottom,width,height])函数,所有值的取值范围都是0-1,代表它与Figure的比值。
您可以使用多个figure方法来创建多个Figure。当前,每一个figure可以包含多少axes和子图,您说了算。
In [9]:
importmatplotlib.pyplotaspltplt.figure(1)# 第一个Figureplt.subplot(211)plt.plot([1,2,3])plt.subplot(212)plt.plot([4,5,6])plt.figure(2)# 第二个Figureplt.plot([4,5,6])plt.figure(1)plt.subplot(211)plt.title('Easy')
Out[9]:
Text(0.5, 1.0, 'Easy')
您可以用clf来清除当前figure,也可以用cla来清除当前axes。如果您创建了很多个figure,您需要知道一件事儿,在figure显式的调用close方法之前,内存中的figure对象是不会被释放的。即使是删除它的所有引用,或用在窗口中关闭都不够,因为pyplot还在内部引用它。
text方法被用于在任意位置添加文本,xlabel,ylabel和title被用于在指定位置添加文本。
In [13]:
mu,sigma=100,15x=mu+sigma*np.random.randn(10000)n,bins,patches=plt.hist(x,50,density=True,facecolor='g',alpha=0.75)#数据直方图plt.xlabel('Smarts')plt.ylabel('Probability')plt.title('Histogram of IQ')plt.text(60,0.025,r'$\mu=100,\ \sigma=15$')#位置是坐标系的坐标点plt.axis([40,160,0,0.03])# x,y轴的显示范围plt.grid(True)plt.show()
所有的text方法返回一个matplotlib.text,Text实例,您可以通过传入关键字参数来text来定制特性或者用setp也可以。 t = plt.xlabel('My data',fontsize=14,color='red')
plt.title(r'$\sigma_i=15$')
上面基础的text方法可以放置到Axes的任意位置,文本的一个常见用途是注释绘图的某些特征,annotate方法提供了一些方便的功能。在一个注释里,需要考虑两点:由参数xy表示的注释位置和文本xytext的位置,这两个参数都是(x,y)元组。
In [14]:
ax=plt.subplot()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()
在这个示例里,不管xy(箭尖)和xytext(文本位置)都在数据坐标中。
matplotlib.pyplot不仅支持线性轴刻度,还支持对数和逻辑回归刻度。如果数据跨越多个数量级,则通常使用此方法。更改轴的比例很简单: plt.xscal('log') 一个例子,四个图,用相同的数据,不同的y轴比例
In [15]:
# Fixing random state for reproducibilitynp.random.seed(19680801)# make up some data in the open 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 scalesplt.figure()# linearplt.subplot(221)plt.plot(x,y)plt.yscale('linear')plt.title('linear')plt.grid(True)# logplt.subplot(222)plt.plot(x,y)plt.yscale('log')plt.title('log')plt.grid(True)# symmetric logplt.subplot(223)plt.plot(x,y-y.mean())plt.yscale('symlog',linthresh=0.01)plt.title('symlog')plt.grid(True)# logitplt.subplot(224)plt.plot(x,y)plt.yscale('logit')plt.title('logit')plt.grid(True)# 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()
In [ ]:
s