如何使用pyplot(Python)使轴占用多个子图

Sve*_*ven 37 python matplotlib

我想在单个图中有三个图.该图应具有2×2的子图布局,其中第一个图应占据前两个子图单元(即整个第一行图单元),其他图应位于单元3和4中的第一个图下方.我知道matlab允许这样使用subplot命令

subplot(2,2,[1,2]) % the plot will span subplots 1 and 2
Run Code Online (Sandbox Code Playgroud)

在pyplot中是否也可以让单个轴占用多个子图?pyplot.subplot的docstring没有谈论它.

谁有一个简单的解决方案?提前致谢

Eri*_*got 45

你可以简单地做:

x = numpy.arange(0, 7, 0.01)

subplot(2, 1, 1)
plot(x, sin(x))

subplot(2, 2, 3)
plot(x, cos(x))

subplot(2, 2, 4)
plot(x, sin(x)*cos(x))
Run Code Online (Sandbox Code Playgroud)

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

  • 虽然这回答了问题中给出的具体示例,但目前还不清楚这是如何适用于不是2的幂的布局.对于我的代码,我想将布局拆分为三分之一.填充右边三分之二的图和另一个填充左三分之一的图. (7认同)
  • 这个答案已经很老了,而且基本上不被鼓励。请参阅下面的“gridspec”和“subplot_mosaic”响应。 (3认同)
  • 这个答案实际上适用于常规布局(没有"2的幂"约束):`subplot(3,1,1)`,例如,削减三分之一.现在,您想要的是由[axes_grid](http://matplotlib.org/gallery.html#axes_grid)工具包处理. (2认同)
  • @EOL,我想的是三分之二,而不是三分之一。例如,我有两个 subplot ,只有 1 列,第一个跨度 2/3,第二个跨度 1/3。这怎么可能做到呢?谢谢。 (2认同)

Hoo*_*ndi 31

要使多个子图占据轴,您可以简单地执行:

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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

另一种方式是

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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Jod*_*mak 16

更现代的答案是:最简单的可能是使用 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()
Run Code Online (Sandbox Code Playgroud)

带 subplot_mosaic 的示例


A.W*_*Wan 11

对于更细粒度的控制,您可能希望使用subplot2grid模块matplotlib.pyplot.

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

  • 非常酷,不知道这个,正是我需要的,尤其是 colspan 和 rowspan 功能。 (2认同)

Imp*_*est 7

使用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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


pyl*_*ang 7

matplotlib 中有三个主要选项可用于在图中绘制单独的图:

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

到目前为止,这些帖子已经解决了前两个选项,但没有提到第三个,这是更现代的方法,并且基于前两个选项。请参阅具体文档使用 subplots 和 GridSpec 组合两个子图。


更新

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


Han*_*ang 6

我能想到两种更灵活的解决方案。

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

影响:

subplot_马赛克图片

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

影响:

次要情节图片

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