概述
使用 Matplotlib 除可以生成包含多条折线的复式折线图之外,它还允许在一张数据图上包含多个子图。
调用 subplot() 函数可以创建一个子图,然后程序就可以在子图上进行绘制。subplot(nrows, ncols, index, **kwargs) 函数的 nrows 参数指定将数据图区域分成多少行;ncols 参数指定将数据图区域分成多少列;index 参数指定获取第几个区域。
subplot() 函数也支持直接传入一个三位数的参数,其中第一位数将作为 nrows 参数;第二位数将作为 ncols 参数;第三位数将作为 index 参数。
下面程序示范了生成多个子图:
import matplotlib.pyplot as plt import numpy as np plt.figure() # 定义从-pi到pi之间的数据,平均取64个数据点 x_data = np.linspace(-np.pi, np.pi, 64, endpoint=True) # ① # 将整个figure分成两行两列,第三个参数表示该图形放在第1个网格 plt.subplot(2, 2, 1) # 绘制正弦曲线 plt.plot(x_data, np.sin(x_data)) plt.gca().spines['right'].set_color('none') plt.gca().spines['top'].set_color('none') plt.gca().spines['bottom'].set_position(('data', 0)) plt.gca().spines['left'].set_position(('data', 0)) plt.title('正弦曲线') # 将整个figure分成两行两列,并将该图形放在第2个网格 plt.subplot(222) # 绘制余弦曲线 plt.plot(x_data, np.cos(x_data)) plt.gca().spines['right'].set_color('none') plt.gca().spines['top'].set_color('none') plt.gca().spines['bottom'].set_position(('data', 0)) plt.gca().spines['left'].set_position(('data', 0)) plt.title('余弦曲线') # 将整个figure分成两行两列,并该图形放在第3个网格 plt.subplot(223) # 绘制正切曲线 plt.plot(x_data, np.tan(x_data)) plt.gca().spines['right'].set_color('none') plt.gca().spines['top'].set_color('none') plt.gca().spines['bottom'].set_position(('data', 0)) plt.gca().spines['left'].set_position(('data', 0)) plt.title('正切曲线') plt.show()
上面程序多次调用 subplot() 函数来生成子图,每次调用 subplot() 函数之后的代码表示在该子图区域绘图。上面程序将整个数据图区域分成 2×2 的网格,程序分别在第 1 个网格中绘制正弦曲线,在第 2 个网格中绘制余弦曲线,在第 3 个网格中绘制正切曲线。
可能有读者感到疑问,plot() 函数不是用于绘制折线图的吗?怎么此处还可用于绘制正弦曲线、余弦曲线呢?
其实此处绘制的依然是折线图。看程序中的 ① 号代码调用 numpy 的 linspace() 函数生成了一个包含多个数值的列表,该数值列表的范围是从 -pi 到 pi,平均分成 64 个数据点,程序中用到的 numpy.sin()、numpy.cos()、numpy.tan() 等函数也返回一个列表:传入这些函数的列表包含多少个值,这些函数返问的列表也包含多少个值。
这意味着上面程序所给制的折线图会包含 64 个转折点,由于这些转折点非常密集,看上去显得比较光滑,因此就变成了曲线。
如果读者将程序中x_data=np.linespace(-np.pi,np.pi,64,endpoint = True)代码的 64 改为4、6等较小的数,将会看到程序绘制的依然是折线图。
运行上面程序,可以看到如图 1 所示的效果。
图 1 生成多个子图
如图 1 所示的显示效果比较差,程序明明只要显示 3 个子图,但第 4 个位置被空出来了,能不能让某个子图占多个网格昵?答案是肯定的,程序做好控制即可。例如,将上面程序改为如下形式:
import matplotlib.pyplot as plt import numpy as np plt.figure() # 定义从-pi到pi之间的数据,平均取64个数据点 x_data = np.linspace(-np.pi, np.pi, 64, endpoint=True) # ① # 将整个figure分成两行一列,第三个参数表示该图形放在第1个网格 plt.subplot(2, 1, 1) # 省略绘制正弦曲线 ... # 将整个figure分成两行两列,并将该图形放在第4个网格 plt.subplot(223) # 省略绘制余弦曲线 ... # 将整个figure分成两行两列,并该图形放在第4个网格 plt.subplot(224) #省略绘制正切曲线 ... plt.show()
上面程序中第 8 行代码将整个区域分成两行一列,并指定子图占用第 1 个网格,也就是整个区域的第一行:第 13 行代码将整个区域分成两行两列,并指定子图占用第 3 个网格(注意不是第 2 个网络,因为第一个子图已经占用了第一行,对于两行两列的网格来说,第一个子图已经占用了两个网格,因此此处指定子图占用第 3 个网格,这意味着该子图在第二行第一格);第 18 行代码将整个区域分成两行两列,并指定子图占用第 4 个网格,这意味着该子图会在第二行第二格。
运行上面程序,可以看到如图 2 所示的效果。
图 2 控制多个子图的分布
如果读者不想这么费劲来计算行、列,将上面程序改为如下形式:
import matplotlib.pyplot as plt import numpy as np import matplotlib.gridspec as gridspec plt.figure() # 定义从-pi到pi之间的数据,平均取64个数据点 x_data = np.linspace(-np.pi, np.pi, 64, endpoint=True) # ① # 将绘图区域分成2行3列 gs = gridspec.GridSpec(2, 3) # 指定ax1占用第一行(0)整行 ax1 = plt.subplot(gs[0, :]) # 指定ax1占用第二行(1)的第一格(第二个参数0代表) ax2 = plt.subplot(gs[1, 0]) # 指定ax1占用第二行(1)的第二、三格(第二个参数0代表) ax3 = plt.subplot(gs[1, 1:3]) # 绘制正弦曲线 ax1.plot(x_data, np.sin(x_data)) ax1.spines['right'].set_color('none') ax1.spines['top'].set_color('none') ax1.spines['top'].set_color('none') ax1.spines['bottom'].set_position(('data', 0)) ax1.spines['left'].set_position(('data', 0)) ax1.set_title('正弦曲线') # 绘制余弦曲线 ax2.plot(x_data, np.cos(x_data)) ax2.spines['right'].set_color('none') ax2.spines['top'].set_color('none') ax2.spines['bottom'].set_position(('data', 0)) ax2.spines['left'].set_position(('data', 0)) ax2.set_title('余弦曲线') # 绘制正切曲线 ax3.plot(x_data, np.tan(x_data)) ax3.spines['right'].set_color('none') ax3.spines['top'].set_color('none') ax3.spines['bottom'].set_position(('data', 0)) ax3.spines['left'].set_position(('data', 0)) ax3.set_title('正切曲线') plt.show()
上面程序中的第 10 行代码将绘图区域分成两行三列;第 12 行代码调用 subplot(gs[0,:]),指定 ax1子图区域占用第一行整行,其中第一个参数 0 代表行号,没有指定列范围,因此该子图在整个第一行;第 14 行代码调用 subplot(gs[1, 0]),指定 ax2 子图区域占用第二行的第一格,其中第一个参数 1 代表第二行,第二个参数 0 代表第一格,因此该子图在第二行的第一格;第 16 行代码调用 subplot(gs [1 , 1 : 3]),指定 ax3 子图区域占用第二行的第二格到第三格,其中第一个参数 1 代表第二行,第二个参数 1:3 代表第二格到第三格,因此该子图在第二行的第二格到第三格。
定义完 ax1、ax2、ax3 这 3 个子图所占用的区域之后,接下来程序就可以通过 ax1、ax2、ax3 的方法在各自的子图区域绘图了。运行上面程序,可以看到如图 3 所示的效果。
图 3 使用 GridSpec 管理子图的分布
最后
以上就是感性吐司为你收集整理的python plt.subplot_Python Matplotlib subplot函数详解:创建子图的全部内容,希望文章能够帮你解决python plt.subplot_Python Matplotlib subplot函数详解:创建子图所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复