<think>
我们使用Matplotlib绘制多图有两种主要方式:
1. 使用`plt.subplot()`创建子图
2. 使用`plt.subplots()`同时创建多个子图
下面我将详细说明这两种方法,并给出示例代码。
### 方法一:使用`plt.subplot()`
这种方法逐个添加子图,通过指定行数、列数以及当前子图的位置索引来创建子图。
语法:
```python
plt.subplot(n_rows, n_cols, index)
```
然后像绘制单个图一样使用`plt.plot()`等函数,这些操作将作用于当前子图。
示例:绘制2x2的子图,共4个图
```python
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
x = np.linspace(0, 2*np.pi, 100)
plt.figure(figsize=(10, 8)) # 设置整个图像的大小
# 第一个子图
plt.subplot(2, 2, 1) # 2行2列,第1个位置
plt.plot(x, np.sin(x))
plt.title('sin(x)')
# 第二个子图
plt.subplot(2, 2, 2) # 2行2列,第2个位置
plt.plot(x, np.cos(x))
plt.title('cos(x)')
# 第三个子图
plt.subplot(2, 2, 3) # 2行2列,第3个位置
plt.plot(x, np.tan(x))
plt.title('tan(x)')
# 第四个子图
plt.subplot(2, 2, 4) # 2行2列,第4个位置
plt.plot(x, np.exp(x))
plt.title('exp(x)')
# 调整子图之间的间距
plt.tight_layout()
plt.show()
```
### 方法二:使用`plt.subplots()`(推荐)
这种方法一次性创建所有子图,并返回一个包含所有子图对象的数组。使用这种方法可以更方便地操作每个子图。
语法:
```python
fig, axs = plt.subplots(n_rows, n_cols, figsize=(width, height))
```
其中`axs`是一个二维数组(当行数或列数大于1时),每个元素代表一个子图对象。
示例:同样绘制2x2的子图
```python
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
x = np.linspace(0, 2*np.pi, 100)
# 创建2x2的子图,并设置整个图像大小
fig, axs = plt.subplots(2, 2, figsize=(10, 8))
# 现在axs是一个2x2的数组,我们可以通过索引访问每个子图
# 绘制第一个子图(第0行,第0列)
axs[0, 0].plot(x, np.sin(x))
axs[0, 0].set_title('sin(x)')
# 第二个子图(第0行,第1列)
axs[0, 1].plot(x, np.cos(x))
axs[0, 1].set_title('cos(x)')
# 第三个子图(第1行,第0列)
axs[1, 0].plot(x, np.tan(x))
axs[1, 0].set_title('tan(x)')
# 第四个子图(第1行,第1列)
axs[1, 1].plot(x, np.exp(x))
axs[1, 1].set_title('exp(x)')
# 调整布局
plt.tight_layout()
plt.show()
```
### 注意:
1. 当子图只有一行或一列时,`axs`将是一维数组。
例如:`fig, axs = plt.subplots(1, 2)`,则`axs[0]`和`axs[1]`分别代表两个子图。
2. 使用`set_title()`、`set_xlabel()`等方法设置子图的标题和坐标轴标签。
3. `plt.tight_layout()`可以自动调整子图参数,避免重叠。
### 高级用法:合并子图(跨多行多列)
使用`subplot2grid`或`GridSpec`可以实现更复杂的布局,例如一个子图占据多行或多列。
示例(使用`subplot2grid`):
```python
plt.figure(figsize=(10, 8))
# 创建一个3x3的网格,第一个子图占据第一行两列
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2, rowspan=1)
ax1.plot(x, np.sin(x))
ax1.set_title('sin(x)')
# 第二个子图占据第一行第三列和第二行第三列(跨两行)
ax2 = plt.subplot2grid((3, 3), (0, 2), rowspan=2)
ax2.plot(x, np.cos(x))
ax2.set_title('cos(x)')
# 第三个子图占据第三行全部(跨三列)
ax3 = plt.subplot2grid((3, 3), (2, 0), colspan=3)
ax3.plot(x, np.tan(x))
ax3.set_title('tan(x)')
plt.tight_layout()
plt.show()
```
使用`GridSpec`可以实现同样的效果,但更灵活,这里不展开。
以上就是在Matplotlib中绘制多图的方法。根据需求选择合适的方式。
### 相关问题
1. 如何设置所有子图共享X轴或Y轴刻度?
2. 如何为整个图形添加一个总标题?
3. 如何在子图中添加图例?
4. 如何保存包含多个子图的高分辨率图像?
5. 如何绘制不同类型图表(如柱状图、散点图)在同一张图的多个子图中?
希望这些方法能帮助你有效地组织多个图表在同一张图中展示[^1][^2]。
</think>
在 Python 中使用 Matplotlib 将多个图像绘制在同一张图中,主要有以下几种方法:
### 一、使用基本子图布局 (subplot)
这是最常用的方法,通过指定网格布局创建多个子图:
```python
import matplotlib.pyplot as plt
import numpy as np
# 创建 2×2 的子图布局
plt.figure(figsize=(10, 8))
# 第一个子图
plt.subplot(2, 2, 1) # (行数, 列数, 位置索引)
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x))
plt.title('正弦函数')
# 第二个子图
plt.subplot(2, 2, 2)
plt.plot(x, np.cos(x), 'r--')
plt.title('余弦函数')
# 第三个子图
plt.subplot(2, 2, 3)
plt.plot(x, np.tan(x), 'g-')
plt.title('正切函数')
# 第四个子图
plt.subplot(2, 2, 4)
plt.plot(x, np.exp(-x), 'm:')
plt.title('指数衰减')
plt.tight_layout() # 自动调整子图间距
plt.show()
```
### 二、面向对象方式 (subplots)
更推荐的方法,可直接获取 Axes 对象数组:
```python
fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(10, 8))
# 访问子图
axs[0, 0].plot(x, np.sin(x))
axs[0, 0].set_title('正弦函数')
axs[0, 0].grid(True)
axs[0, 1].plot(x, np.cos(x), 'r--')
axs[0, 1].set_title('余弦函数')
axs[1, 0].scatter(x, np.random.randn(100), c='g')
axs[1, 0].set_title('随机散点图')
axs[1, 1].hist(np.random.randn(1000), bins=30, color='purple')
axs[1, 1].set_title('正态分布直方图')
fig.suptitle('多图示例', fontsize=16) # 添加总标题
plt.tight_layout()
plt.show()
```
### 三、复杂布局 (GridSpec)
对于不对称布局,使用 GridSpec:
```python
from matplotlib.gridspec import GridSpec
fig = plt.figure(figsize=(12, 8))
gs = GridSpec(3, 3, figure=fig) # 3行3列
# 左上角大图 (占据第0行,前两列)
ax1 = fig.add_subplot(gs[0, :2])
ax1.plot(x, np.sin(x) * np.exp(-x/2))
# 右上角小图 (占据第0行,第2列)
ax2 = fig.add_subplot(gs[0, 2])
ax2.pie([30, 40, 30])
# 底部长图 (占据第1-2行,全部列)
ax3 = fig.add_subplot(gs[1:, :])
ax3.imshow(np.random.rand(20, 20), cmap='viridis')
plt.tight_layout()
plt.show()
```
### 四、叠加绘图 (Overlay)
在同一坐标系叠加多个图形:
```python
plt.figure(figsize=(8, 6))
# 叠加三条曲线
x = np.linspace(0, 4*np.pi, 200)
plt.plot(x, np.sin(x), label='sin(x)')
plt.plot(x, np.cos(x), label='cos(x)')
plt.plot(x, np.sin(x)+np.cos(x), 'k--', label='sin(x)+cos(x)')
plt.title('三角函数叠加')
plt.xlabel('x')
plt.ylabel('y')
plt.legend() # 显示图例
plt.grid(alpha=0.3)
plt.show()
```
### 关键技巧
1. **布局调整**:
- 使用 `plt.tight_layout()` 自动调整子图间距
- 手动调整:`plt.subplots_adjust(wspace=0.3, hspace=0.4)`
2. **共享坐标轴**:
```python
fig, axs = plt.subplots(2, 2, sharex=True, sharey=True)
```
3. **添加统一元素**:
```python
fig.text(0.5, 0.04, '公共X轴', ha='center')
fig.text(0.04, 0.5, '公共Y轴', va='center', rotation='vertical')
```
4. **保存高清图**:
```python
plt.savefig('multiplot.png', dpi=300, bbox_inches='tight')
```
> 掌握这些方法可以创建从简单比较到复杂仪表板的各种多图布局[^1][^2]。
### 相关问题
1. 如何在不同子图间共享坐标轴刻度?
2. GridSpec 布局中如何实现单元格合并?
3. 如何为每个子图添加独立图例?
4. Matplotlib 中哪些参数控制子图间距?
5. 如何创建带有共享颜色条的多个热力图?
6. 在 Jupyter Notebook 中如何优化多图的显示效果?