繁体   English   中英

如何使用pyplot使一个轴占据多个子图

[英]How to make an axes occupy multiple subplots with pyplot

我想在一个图中包含三个图。 该图应具有二乘二的子图布局,其中第一个 plot 应占据前两个子图单元格(即 plot 单元格的整个第一行),其他图应位于单元格 3 和 4 中第一个图的下方。

我知道 MATLAB 通过使用subplot命令允许这样做:

subplot(2,2,[1,2]) % the plot will span subplots 1 and 2

在 pyplot 中是否也可以让一个轴占据多个子图? pyplot.subplot的文档字符串没有谈论它。

任何人都有一个简单的解决方案?

你可以简单地做:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 7, 0.01)
    
plt.subplot(2, 1, 1)
plt.plot(x, np.sin(x))
    
plt.subplot(2, 2, 3)
plt.plot(x, np.cos(x))
    
plt.subplot(2, 2, 4)
plt.plot(x, np.sin(x)*np.cos(x))

即,第一个图实际上是上半部分的图(图中仅划分为 2x1 = 2 个单元格),以下两个较小的图是在 2x2=4 个单元格网格中完成的。 subplot()的第三个参数是绘图在网格内的位置(在英文阅读方向,单元格 1 位于左上角):例如在第二个子图中( subplot(2, 2, 3) ),轴将转到 2x2 矩阵的第三部分,即到左下角。

在此处输入图像描述

要让多个子图占据一个轴,您可以简单地执行以下操作:

from matplotlib import pyplot as plt
import numpy as np

b=np.linspace(-np.pi, np.pi, 100)

a1=np.sin(b)

a2=np.cos(b)

a3=a1*a2

plt.subplot(221)
plt.plot(b, a1)
plt.title('sin(x)')

plt.subplot(222)
plt.plot(b, a2)
plt.title('cos(x)')

plt.subplot(212)
plt.plot(b, a3)
plt.title('sin(x)*cos(x)')

plt.show()

在此处输入图像描述

另一种方法是

plt.subplot(222)
plt.plot(b, a1)
plt.title('sin(x)')

plt.subplot(224)
plt.plot(b, a2)
plt.title('cos(x)')

plt.subplot(121)
plt.plot(b, a3)
plt.title('sin(x)*cos(x)')

plt.show()

在此处输入图像描述

使用 Gridspec 制作多列/行子图布局显示了一种使用GridSpec执行此操作的方法。 带有 3 个子图的示例的简化版本如下所示

import matplotlib.pyplot as plt

fig = plt.figure()

gs = fig.add_gridspec(2,2)
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, :])

plt.show()

在此处输入图像描述

对于更细粒度的控制,您可能需要使用matplotlib.pyplotsubplot2grid模块。

http://matplotlib.org/users/gridspec.html

一个更现代的答案是:最简单的可能是使用 subplots_mosaic:https ://matplotlib.org/stable/tutorials/provisional/mosaic.html

import matplotlib.pyplot as plt
import numpy as np

# Some example data to display
x = np.linspace(0, 2 * np.pi, 400)
y = np.sin(x ** 2)

fig, axd = plt.subplot_mosaic([['left', 'right'],['bottom', 'bottom']],
                              constrained_layout=True)
axd['left'].plot(x, y, 'C0')
axd['right'].plot(x, y, 'C1')
axd['bottom'].plot(x, y, 'C2')
plt.show()

带有 subplot_mosaic 的示例

matplotlib 中有三个主要选项可以在图中制作单独的图:

  1. subplot :访问轴数组并添加子图
  2. gridspec :控制底层图形的几何属性( 演示
  3. subplots :将前两个包装在一个方便的 api 中( 演示

到目前为止,这些帖子已经讨论了前两个选项,但他们没有提到第三个,这是更现代的方法,并且基于前两个选项。 请参阅特定文档Combining two subplots using subplots 和 GridSpec


更新

一个更好的改进可能是@Jody Klymak 的帖子中提到的临时subplot_mosaic方法。 它使用结构化的可视化方法来绘制子图,而不是混淆数组索引。 但是,它仍然基于上面提到的后一种选项。

我可以想到 2 个更灵活的解决方案。

  1. 最灵活的方式:使用subplot_mosaic
f, axes = plt.subplot_mosaic('AAB;CDD;EEE')
# axes = {'A': ..., 'B': ..., ...}

影响:

子图_马赛克图片

  1. 使用gridspec_kw of subplots 虽然当不同的行需要不同的宽度比例时也很不方便。
f, (a0, a1) = plt.subplots(1, 2, gridspec_kw={'width_ratios': [2, 1]})

影响:

子图图片

其他答案的subplot方法有点死板,IMO。 例如,您无法轻松创建宽度比为 1:2 和 2:1 的两行。 但是,例如,当您需要覆盖subplots的某些布局时,它会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM