Matplotlib is hiring a Research Software Engineering Fellow! See discourse for details. Apply by January 3, 2020

Version 3.1.1
matplotlib
Fork me on GitHub

目录

Related Topics

使用GRIDSPEC和其他功能自定义图形布局

如何创建轴的网格形状组合。

subplots()
可能是用来创建图形和轴的主要函数。它也类似于 matplotlib.pyplot.subplot() ,但同时创建和放置图形上的所有轴。也见 matplotlib.Figure.subplots .
GridSpec
指定要放置子批次的网格的几何图形。需要设置网格的行数和列数。或者,可以调整子批次布局参数(例如,左、右等)。
SubplotSpec
指定子批次在给定子批次中的位置 GridSpec .
subplot2grid()
类似于 subplot() ,但使用基于0的索引并让子块占据多个单元格。本教程不介绍此功能。
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

基本快速入门指南

前两个示例演示了如何使用这两种方法创建基本的2×2网格 subplots()gridspec .

使用 subplots() 很简单。它返回一个 Figure 实例和数组 Axes 物体。

fig1, f1_axes = plt.subplots(ncols=2, nrows=2, constrained_layout=True)
使用GRIDSPEC和其他功能自定义图形布局

对于这样一个简单的用例, gridspec 可能过于冗长。你必须创造人物 GridSpec 分别执行实例,然后将gridspec实例的元素传递给 add_subplot() 方法创建轴对象。gridspec的元素的访问方式通常与numpy数组相同。

fig2 = plt.figure(constrained_layout=True)
spec2 = gridspec.GridSpec(ncols=2, nrows=2, figure=fig2)
f2_ax1 = fig2.add_subplot(spec2[0, 0])
f2_ax2 = fig2.add_subplot(spec2[0, 1])
f2_ax3 = fig2.add_subplot(spec2[1, 0])
f2_ax4 = fig2.add_subplot(spec2[1, 1])
使用GRIDSPEC和其他功能自定义图形布局

gridspec的强大之处在于能够创建跨越行和列的子块。注意 Numpy slice 用于选择每个子块将占用的gridspec部分的语法。

请注意,我们还使用了便利方法 Figure.add_gridspec 而不是 gridspec.GridSpec ,可能会为用户保存导入,并保持命名空间的清洁。

fig3 = plt.figure(constrained_layout=True)
gs = fig3.add_gridspec(3, 3)
f3_ax1 = fig3.add_subplot(gs[0, :])
f3_ax1.set_title('gs[0, :]')
f3_ax2 = fig3.add_subplot(gs[1, :-1])
f3_ax2.set_title('gs[1, :-1]')
f3_ax3 = fig3.add_subplot(gs[1:, -1])
f3_ax3.set_title('gs[1:, -1]')
f3_ax4 = fig3.add_subplot(gs[-1, 0])
f3_ax4.set_title('gs[-1, 0]')
f3_ax5 = fig3.add_subplot(gs[-1, -2])
f3_ax5.set_title('gs[-1, -2]')
使用GRIDSPEC和其他功能自定义图形布局

gridspec 对于通过两种方法创建不同宽度的子批次也是必不可少的。

这里显示的方法与上面的方法类似,初始化统一的网格规范,然后使用numpy索引和切片为给定的子批次分配多个“单元”。

fig4 = plt.figure(constrained_layout=True)
spec4 = fig4.add_gridspec(ncols=2, nrows=2)
anno_opts = dict(xy=(0.5, 0.5), xycoords='axes fraction',
                 va='center', ha='center')

f4_ax1 = fig4.add_subplot(spec4[0, 0])
f4_ax1.annotate('GridSpec[0, 0]', **anno_opts)
fig4.add_subplot(spec4[0, 1]).annotate('GridSpec[0, 1:]', **anno_opts)
fig4.add_subplot(spec4[1, 0]).annotate('GridSpec[1:, 0]', **anno_opts)
fig4.add_subplot(spec4[1, 1]).annotate('GridSpec[1:, 1:]', **anno_opts)
使用GRIDSPEC和其他功能自定义图形布局

另一种选择是使用 width_ratiosheight_ratios 参数。这些关键字参数是数字列表。请注意,绝对值没有意义,只有它们的相对比率才重要。那意味着 width_ratios=[2, 4, 8] 等于 width_ratios=[1, 2, 4] 在同样宽的数字内。为了演示,我们将在 for 循环,因为我们以后不需要它们。

fig5 = plt.figure(constrained_layout=True)
widths = [2, 3, 1.5]
heights = [1, 3, 2]
spec5 = fig5.add_gridspec(ncols=3, nrows=3, width_ratios=widths,
                          height_ratios=heights)
for row in range(3):
    for col in range(3):
        ax = fig5.add_subplot(spec5[row, col])
        label = 'Width: {}\nHeight: {}'.format(widths[col], heights[row])
        ax.annotate(label, (0.1, 0.5), xycoords='axes fraction', va='center')
使用GRIDSPEC和其他功能自定义图形布局

学会使用 width_ratiosheight_ratios 特别有用,因为顶级功能 subplots() 接受他们在 gridspec_kw 参数。就这一点而言,任何被 GridSpec 可以传递给 subplots() 通过 gridspec_kw 参数。此示例在不直接使用gridspec实例的情况下重新创建上一个图。

gs_kw = dict(width_ratios=widths, height_ratios=heights)
fig6, f6_axes = plt.subplots(ncols=3, nrows=3, constrained_layout=True,
        gridspec_kw=gs_kw)
for r, row in enumerate(f6_axes):
    for c, ax in enumerate(row):
        label = 'Width: {}\nHeight: {}'.format(widths[c], heights[r])
        ax.annotate(label, (0.1, 0.5), xycoords='axes fraction', va='center')
使用GRIDSPEC和其他功能自定义图形布局

这个 subplotsgridspec 方法可以组合,因为有时使用 subplots 然后取下一些并合并。这里我们创建一个布局,最后一列中底部的两个轴组合在一起。

fig7, f7_axs = plt.subplots(ncols=3, nrows=3)
gs = f7_axs[1, 2].get_gridspec()
# remove the underlying axes
for ax in f7_axs[1:, -1]:
    ax.remove()
axbig = fig7.add_subplot(gs[1:, -1])
axbig.annotate('Big Axes \nGridSpec[1:, -1]', (0.1, 0.5),
               xycoords='axes fraction', va='center')

fig7.tight_layout()
使用GRIDSPEC和其他功能自定义图形布局

网格规格布局的微调

显式使用gridspec时,可以调整从gridspec创建的子批次的布局参数。注意:此选项与不兼容 constrained_layoutFigure.tight_layout 两者都可以调整子批次大小来填充数字。

fig8 = plt.figure(constrained_layout=False)
gs1 = fig8.add_gridspec(nrows=3, ncols=3, left=0.05, right=0.48, wspace=0.05)
f8_ax1 = fig8.add_subplot(gs1[:-1, :])
f8_ax2 = fig8.add_subplot(gs1[-1, :-1])
f8_ax3 = fig8.add_subplot(gs1[-1, -1])
使用GRIDSPEC和其他功能自定义图形布局

这和 subplots_adjust() 但它只影响从给定的gridspec创建的子批次。

例如,比较此图的左侧和右侧:

fig9 = plt.figure(constrained_layout=False)
gs1 = fig9.add_gridspec(nrows=3, ncols=3, left=0.05, right=0.48,
                        wspace=0.05)
f9_ax1 = fig9.add_subplot(gs1[:-1, :])
f9_ax2 = fig9.add_subplot(gs1[-1, :-1])
f9_ax3 = fig9.add_subplot(gs1[-1, -1])

gs2 = fig9.add_gridspec(nrows=3, ncols=3, left=0.55, right=0.98,
                        hspace=0.05)
f9_ax4 = fig9.add_subplot(gs2[:, :-1])
f9_ax5 = fig9.add_subplot(gs2[:-1, -1])
f9_ax6 = fig9.add_subplot(gs2[-1, -1])
使用GRIDSPEC和其他功能自定义图形布局

使用子图规范的网格规范

您可以从 SubplotSpec ,在这种情况下,其布局参数设置为给定子批次规范的位置。

注意这也可以从更详细的 gridspec.GridSpecFromSubplotSpec .

fig10 = plt.figure(constrained_layout=True)
gs0 = fig10.add_gridspec(1, 2)

gs00 = gs0[0].subgridspec(2, 3)
gs01 = gs0[1].subgridspec(3, 2)

for a in range(2):
    for b in range(3):
        fig10.add_subplot(gs00[a, b])
        fig10.add_subplot(gs01[b, a])
使用GRIDSPEC和其他功能自定义图形布局

使用子块规范的复杂嵌套网格规范

下面是一个更复杂的嵌套gridspec示例,我们在外部4x4网格的每个单元格周围放置一个框,通过在内部3x3网格中隐藏适当的尖刺。

import numpy as np
from itertools import product


def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)):
    return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d)


fig11 = plt.figure(figsize=(8, 8), constrained_layout=False)

# gridspec inside gridspec
outer_grid = fig11.add_gridspec(4, 4, wspace=0.0, hspace=0.0)

for i in range(16):
    inner_grid = outer_grid[i].subgridspec(3, 3, wspace=0.0, hspace=0.0)
    a, b = int(i/4)+1, i % 4+1
    for j, (c, d) in enumerate(product(range(1, 4), repeat=2)):
        ax = plt.Subplot(fig11, inner_grid[j])
        ax.plot(*squiggle_xy(a, b, c, d))
        ax.set_xticks([])
        ax.set_yticks([])
        fig11.add_subplot(ax)

all_axes = fig11.get_axes()

# show only the outside spines
for ax in all_axes:
    for sp in ax.spines.values():
        sp.set_visible(False)
    if ax.is_first_row():
        ax.spines['top'].set_visible(True)
    if ax.is_last_row():
        ax.spines['bottom'].set_visible(True)
    if ax.is_first_col():
        ax.spines['left'].set_visible(True)
    if ax.is_last_col():
        ax.spines['right'].set_visible(True)

plt.show()
使用GRIDSPEC和其他功能自定义图形布局