我们进入下一个阶段:面向对象绘图
matplotlib的前身是matlab,事实上,前两章的模块调用与matlab并无差异,无非就是将matlab语法换成python语法。遵循的仍然是顺序调用,接口传参,而后得到绘图结果的过程。
而这是远远不够的,举个简单的例子,当我们得到绘图对象后,我们可能对绘图对象的横坐标尺度不够满意,比如原横坐标是每个0.1产生一个刻度,而我们需要每隔0.5产生一个尺度;有时,我们对图例是不够满意的,原图例是5行1列,而我们想将其设置为1行5列。解决这些问题,需要的是面向对象的思路,就一幅图而言,其对象由总到分可以概括为:
对象 | 常用代号 |
---|---|
画布 | fig |
子图(或者坐标系) | ax |
绘图对象(如散点,直方、折线等) | ax.scatter、ax.hist、ax.plot |
坐标轴 | ax.xaxis |
坐标轴刻度 | ax.xaxis.xtick |
图例 | ax.legend |
轴标题 | ax.xlabel |
从表中可以看出,大多数对象都从属于ax,而ax是根植在fig基础上的,本文重点探讨fig与ax的关系
本文的运行环境为 jupyter notebook
python版本为3.7
本文所用到的库包括
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
单子图
当画布上只有一副子图时,以下两段代码并无差异,plt会自动创建一副子图并绘制图像。
x=np.sin(np.linspace(1,10,100))
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
ax.plot(x)
x=np.sin(np.linspace(1,10,100))
plt.plot(x)
但是,大多数情况下,我们都需要绘制多个子图,在一张画布上绘制多个子图一共分为三种思路,请往下看。
思路一:创建画布,在画布基础上创建子图
刚思路需先创建一个画布对象fig,并以此为基础,通过调用fig.add_subplot接口或fig.add_axes接口,逐个创建子图ax,后通过ax进行绘图对象的绘制及子图的修改。两者原理亦有些差别。
fig.add_subplot
nrows, ncols=2,3
fig=plt.figure(figsize=(8,6))
for i in range(nrows*ncols):
ax=fig.add_subplot(nrows, ncols,i+1)
### 子图的绘制 ###
设置坐标系
需要注意的是,在创建子图时,可以根据具体需求,对子图的坐标系进行设定。
下图展示了不同坐标系下,正弦折线图的差异。从下图可知,我们常用的坐标系为rectilinear
x = np.linspace(-1.0*np.pi, np.pi, 100)
y = np.sin(x)
nrows, ncols = 2, 3
fig = plt.figure(figsize=(8, 6))
for i, projection in enumerate(['aitoff', 'hammer