介绍
所有的函数曲线都要画在坐标系内,就比如二维的坐标就是x,y坐标轴,并且两个坐标轴相互垂直。在Matplotlib中,使用Axes容器来描述坐标系,为什么说它是一个容器,因为它包含了坐标系中各个轴的刻度线,刻度值,以及坐标网格和坐标轴标题等----都可以看作Axes容器里面的对象。
坐标网格
坐标中有网格可以方便我们去观察曲线的每个点的坐标值。
import matplotlib.pylab as plt
import numpy as np
x = np.arange(0.0,5.0,0.02)
y = np.exp(-x)*np.cos(2*np.pi*x)
plt.plot(x,y)
plt.grid(color='gray')
plt.show()
还可以使用面向对象的形式:
x = np.arange(0.0,5.0,0.02)
y = np.exp(-x)*np.cos(2*np.pi*x)
fig = plt.figure()
a = fig.add_axes([0.1,0.1,0.8,0.8])
plt.plot(x,y)
plt.grid(color='gray')
plt.show()
效果也是一样的,不管使用上面方式都要绘制坐标网格,都要执行grid()方法,除了可以设置color以外还可以设置axis,默认为both,可以设置为x或者y表示表格线是垂直与x轴还是y轴的,还可以设置linestyle,表示设置表格线的线性,还可以设置linewidth,表示设置表格线的宽度。
坐标轴
x = np.arange(0.0,5.0,0.02)
y = np.exp(-x)*np.cos(2*np.pi*x)
fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
plt.plot(x,y)
plt.grid(color='gray')
ax.set_xlabel("x axis") #为x轴设置标题
ax.set_xlim((0,6)) #表示设置x轴的数值范围
plt.show()
也可以使用:
x = np.arange(0.0,5.0,0.02)
y = np.exp(-x)*np.cos(2*np.pi*x)
plt.plot(x,y)
plt.grid(color='gray')
plt.title("show") #设置坐标名
plt.xlabel("x") #设置x轴名字
plt.ylabel("y") #设置y轴名字
plt.xlim(0,6) #设置x轴的取值范围
plt.show()
上面的方法自行尝试一下,不仅可以设置坐标名还可以设置x轴与y轴的标题,可以使用ax.set_xlim()或者plt.xlim()方法里面传入刻度的范围,即最大值与最小值。
也可以添加plt.xticks(np.linspace())或者ax.set_xticks(np.linspace())都是可以修改刻度x轴或者y轴的刻度,让它更精确一点。
plt.xticks(np.linspace(0,5,11))
分区
如果使用plt.plot()画图,画布上就有一个坐标系,如果使用plt.subplots()画图,就可以生成多个坐标系,每个坐标都是一个Axes容器对象。
观察下面两个函数的方法
help(plt.subplot)
subplot(*args, **kwargs)
help(plt.subplots)
subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, **fig_kw)
运行:
fig,ax = plt.subplots(3,3,sharex='col',sharey='row')
plt.show()
可以看到生成了9个分区(3*3,sharex=‘col’,sharey='row’相对应的几行几列,还得到一个Figure()对象和ax引用的Axes容器,之后继续输入:
for i in range(3):
for j in range(3):
ax[i,j].text(0.5,0.5,str((i,j)),fontsize=18,ha='center')
使用循环的语句后通过ax[i,j]得到每个分区的Axes对象,text()就是Axes对象的方法,能够往容器中添加文本,再定义字体大小与字体的位置,可以查看帮助文档:
text(x, y, s, fontdict=None, withdash=<deprecated parameter>, **kwargs)
结果如下:
而plt.subplot()的作用就是得到分区中的一个子图,可以通过循环将它应用再分区中:
for i in range(1,10):
plt.subplot(3,3,i)
plt.text(0.5,0.5,str((1,2,i)),fontsize=18,ha='center')
上面的代码plt.subplot(3,3,i)表示输出一个9(3*3)个分区的分布,然后通过循环来进行访问,并创建坐标系,再使用text函数添加文本。
也可以使用面向对象的方法写,效果是一样的:
fig = plt.figure()
fig.subplots_adjust(hspace=0.4,wspace=0.4)
for i in range(1,10):
ax = fig.add_subplot(3,3,i)
ax.text(0.5,0.5,str((1,2,i)),fontsize=18,ha='center')
上面代码使用了Figure对象的add_subplot()方法来增加分区,效果与plt.subplot相同,fig.subplots_adjust(hspace=0.4,wspace=0.4)则是表示设置相邻分区的间距,分别表示为间距的分区长或宽的40%。
在同一个画布上创建多个Axes对象,等同于坐标系:
fig = plt.figure()
ax1 = fig.add_axes([0.1,0.1,0.8,0.8])
ax2 = fig.add_axes([0.5,0.3,0.2,0.2])
ax3 = fig.add_axes([0.2,0.6,0.2,0.2])
观察上面的代码fig.add_axes这里面的4个参数分别是对照[left,bottom,width,height]顺序确定的Axes对象的位置与大小,left与bottom表示的是距离画布的左边与底部的距离,数值为画布宽与高的百分比,width和height分别表示子图的宽高,也是百分比,比如ax1 = fig.add_axes([0.1,0.1,0.8,0.8])表示的就是距离画布左边与底部10%的距离,以及子图的高宽为80%
上面的面向对象的风格写的,当然也可以使用matlab风格编写,就要运用到我们的plt.axes()函数了,效果是一样的:
plt.axes([0.1,0.1,0.8,0.8])
plt.axes([0.5,0.3,0.2,0.2])
plt.axes([0.2,0.6,0.2,0.2])
plt.show()
还有一个方法可以灵活的创建分区,就是plt.GridSpec()函数了:
a = plt.GridSpec(3,3,hspace=0.4,wspace=0.4)
plt.subplot(a[:2,0])
plt.subplot(a[:2,1])
plt.subplot(a[:2,2])
plt.subplot(a[2,0:])
plt.show()
上面那个plt.GridSpec(3,3,hspace=0.4,wspace=0.4)表示的就是将创建的画布划分为9(3*3)个网格,之后使用plt.subplot()函数进行对变量a所引用的对象进行切片,类似于多维数组切片,关于切片可以参考Numpy的索引与切片,结果如下:
总结
画图的过程大致可以分为以下几个步骤:
1.首先创建Figure对象,就是画布,要有画布才能在上面画画。
2.使用subplot()或者subplots等函数创建分区,就是将一块画布分为几个小的部分。
3.记得创建Axes容器对象,在分区上创建坐标系,不然东西放哪。
4.在Axes容器内画图。