[ Matplotlib version: 3.2.1 ]
有时候需要从多个角度对数据进行对比。
Matplotlib为此剔除了子图(subplot)的概念:在较大的图形中同时放置一组较小的坐标轴。这些子图可能是画中画(inset)、网格图(grid of plots),或者是其他更复杂的布局形式。
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
创建坐标轴最基本的方法就是使用plt.axes
函数。
[bottom, left, width, height]
(底坐标、左坐标、宽度、高度),数值的取值范围是左下角(原点)为0,右上角为1plt.add_axes()
# 右上角创建一个画中画
# 先将x与y设置为0.65(坐标轴原点位于图形高度65%和宽度65%的位置)
# 然后将x与y扩展到0.2(将坐标轴的宽度与高度设置为图形的20%)
ax1 = plt.axes() # 默认坐标轴
ax2 = plt.axes([0.65, 0.65, 0.2, 0.2])
# 创建两个竖直排列的坐标轴
fig = plt.figure()
ax1 = fig.add_axes([0.1, 0.5, 0.8, 0.4],
xticklabels=[], ylim=(-1.2, 1.2))
ax2 = fig.add_axes([0.1, 0.1, 0.8, 0.4],
ylim=(-1.2, 1.2))
x = np.linspace(0, 10)
ax1.plot(np.sin(x))
ax2.plot(np.cos(x))
若干彼此对齐的行列子图是常见的可视化任务。Matplotlib提供一些简便方法:
plt.subplot()
在一个网格中创建一个子图。plt.subplot()
有三个整型参数:将要创建的网格子图行数、列数和索引值,索引值从1开始,从左上角到右下角依次增大plt.subplots_adjust
可以调整子图之间的间隔。用面向对象接口的命令fig.add_subplot()
有同样的效果for i in range(1, 7):
plt.subplot(2, 3, i)
plt.text(0.5, 0.5, str((2, 3, i)),
fontsize=18, ha='center')
# 通过plt.subplots_adjust的hspace与wspace参数设置与图形高度与宽度一致的子图间距,数值以子图的尺寸为单位
# 间距是子图宽度与高度的40%
fig = plt.figure()
fig.subplots_adjust(hspace=0.4, wspace=0.4)
for i in range(1, 7):
ax = fig.add_subplot(2, 3, i)
ax.text(0.5, 0.5, str((2, 3, i)),
fontsize=18, ha='center')
当要创建一个大型网格子图时,尤其是当需要隐藏内部子图的x轴与y轴标题时,可以用plt.subplots()
实现(前面的方法不可用):
plt.subplots()
不是用来创建单个子图的,而是用一行代码创建多个子图,并返回一个包含子图的NumPy数组plt.subplots()
关键参数是行数与列数,以及可选参数sharex
与sharey
,通过它们可以设置不同子图之间的关联关系plt.subplot()
(索引从1开始)相比,plt.subplots()
与Python索引从0开始的规则保持一致# 创建一个2*3网格子图,每行的3个子图使用相同的y轴坐标,每列的2个子图使用相同的x轴坐标
fig, ax = plt.subplots(2, 3, sharex='col', sharey='row')
sharex
与sharey
参数之后,就可以自动去掉网格内部子图的标签,让图形看起来更加整洁。# 坐标轴存放在一个NumPy数组中,按照[row, col]取值
for i in range(2):
for j in range(3):
ax[i, j].text(0.5, 0.5, str((i, j)),
fontsize=18, ha='center')
如果想实现不规则的多行多列子图网格,plt.GridSpec()
是最好的工具。
plt.GridSpec()
对象本身不能直接创建一个图形,它只是plt.subplot()
命令可以识别的简易接口grid = plt.GridSpec(2, 3, wspace=0.4, hspace=0.3)
plt.subplot(grid[0, 0])
plt.subplot(grid[0, 1:])
plt.subplot(grid[1, :2])
plt.subplot(grid[1, 2])
# 创建一些正态分布数据
mean = [0, 0]
cov = [[1, 1], [1, 2]]
x, y = np.random.multivariate_normal(mean, cov, 3000).T
# 设置坐标轴和网格配置方式
fig = plt.figure(figsize=(6, 6))
grid = plt.GridSpec(4, 4, hspace=0.2, wspace=0.2)
main_ax = fig.add_subplot(grid[:-1, 1:])
y_hist = fig.add_subplot(grid[:-1, 0], xticklabels=[], sharey=main_ax)
x_hist = fig.add_subplot(grid[-1, 1:], yticklabels=[], sharex=main_ax)
# 主坐标轴画散点图
main_ax.plot(x, y, 'ok', markersize=3, alpha=0.2)
# 次坐标轴画频次直方图
x_hist.hist(x, 40, histtype='stepfilled',
orientation='vertical', color='gray')
x_hist.invert_yaxis()
y_hist.hist(y, 40, histtype='stepfilled',
orientation='horizontal', color='gray')
y_hist.invert_xaxis()
Matplotlib 相关阅读:
[Python3] Matplotlib —— (一) 入门基础
[Python3] Matplotlib —— (二) 简易线形图
[Python3] Matplotlib —— (三) 简易散点图
[Python3] Matplotlib —— (四) 可视化异常处理
[Python3] Matplotlib —— (五) 密度图与等高线图
[Python3] Matplotlib —— (六) 频次直方图、数据区间划分和分布密度
[Python3] Matplotlib —— (七) 配置图例
[Python3] Matplotlib —— (八) 配置颜色条
总结自《Python数据科学手册》