首页 > 解决方案 > 如何使用带有多个子图的 matplotlib 吸引人地排列标题和轴标签等图形和文本?

问题描述

我想创建测量系统三轴的前后图。这接近我想要的。然而:

from matplotlib.pyplot import figure

def plot_before_and_after(data_before, data_after, title):
    shape = data_before.shape
    sensor_num = shape[0]
    n_start = 20  # number picked at random
    N = 2 ** 12  # power of two is good
    n_stop = n_start + N
    p_stop = n_start + 40  # one periode @50Hz at the sampling rate
    x_long = range(n_start, n_stop)
    x_short = range(n_start, p_stop)
    
    cmap = plt.get_cmap('jet_r')
    axis_list = ['x', 'y', 'z']
    fig = figure(num=None, figsize=(10, 10), dpi=80, facecolor='w', edgecolor='k')
    
    fig.suptitle(title + "\nbefore \t\t\t\t\tafter")
    plots = []
    for axis_cnt in range(0, 3):
        ax0 = plt.subplot(3, 5, axis_cnt * 5 + 1,
                                              title="before, {}-Axis".format(axis_list[axis_cnt]))
        for sensor_cnt in range(0, sensor_num):
            color = cmap(float(sensor_cnt) / sensor_num)
            plt.plot(x_long, data_before[sensor_cnt, n_start:n_stop, axis_cnt], color=color,
                     label="sensor" + str(sensor_cnt))
    
        ax1 = plt.subplot(3, 5, axis_cnt * 5 + 2,
                                              title="before, {}-Axis".format(axis_list[axis_cnt]),
                                              sharey=ax0)
        for sensor_cnt in range(0, sensor_num):
            color = cmap(float(sensor_cnt) / sensor_num)
            plt.plot(x_short, data_before[sensor_cnt, n_start:p_stop, axis_cnt], color=color,
                     label="sensor" + str(sensor_cnt))
        plt.setp(ax1.get_yticklabels(), visible=False)
    
        ax3 = plt.subplot(3, 5, axis_cnt * 5 + 4,
                                              title="after, {}-Axis".format(axis_list[axis_cnt]))
        for sensor_cnt in range(0, sensor_num):
            color = cmap(float(sensor_cnt) / sensor_num)
            plt.plot(x_long, data_after[sensor_cnt, n_start:n_stop, axis_cnt], color=color,
                     label="sensor" + str(sensor_cnt))
    
        ax4 = plt.subplot(3, 5, axis_cnt * 5 + 5,
                                              title="after, {}-Axis".format(axis_list[axis_cnt]),sharey=ax3)
        for sensor_cnt in range(0, sensor_num):
            color = cmap(float(sensor_cnt) / sensor_num)
            plt.plot(x_short, data_after[sensor_cnt, n_start:p_stop, axis_cnt], color=color,
                     label="sensor" + str(sensor_cnt))
        plt.setp(ax4.get_yticklabels(), visible=False)
    plt.subplots_adjust(wspace=.0)
    plt.legend()
    plt.show()

代码生成时带有多个子图的示例图

标签: pythonmatplotlib

解决方案


这是一个可能对您有所帮助的初步答案。我使用了 Matplotlib 的 GridSpec(有关有用信息,请参阅此处add_subplot)和方法,在这些情况下,这两种方法似乎都很方便。gridspec 允许我们创建两组独立格式化的子图;生成各个add_subplot轴。

代码

import matplotlib.pyplot as plt

nrow, ncol = 3, 2             # Number of rows and cols of gridspecs     
lborder = [0.1, 0.6]          # Left border coordinates of gridspecs
rborder = [0.45, 0.95]        # Right border coordinates of gridspecs
tborder = 0.92                # Top border coordinate of gridspecs
gtitles = ['Before', 'After']
txt_axis = ['X-axis', 'Y-axis', 'Z-axis']

fig = plt.figure(figsize=(10, 10), dpi=80, facecolor='w', edgecolor='k')

for i in range(2):
    gs = fig.add_gridspec(nrows=nrow, ncols=ncol, left=lborder[i], 
                          right=rborder[i], top=tborder, hspace=0.45, wspace=0)
    for j in range(nrow):
        ax0 = fig.add_subplot(gs[j,0])
        ax0.plot([1,2,3])
        plt.text(-0.4, 0.5, txt_axis[j],
                 horizontalalignment='center',verticalalignment='center',
                 transform = ax0.transAxes, fontsize = 12)
        if j == 0:
            fig.text(1, 1.1, gtitles[i], fontsize=12, horizontalalignment = 
                     'center', transform = ax0.transAxes)
        for k in range(1, ncol):
            ax1 = fig.add_subplot(gs[j,k], sharey = ax0)
            plt.setp(ax1.get_yticklabels(), visible=False)
            ax1.plot([1,2,3])
            
fig.suptitle('Figure title', fontsize = 14)

至于你的问题:

  • text我根据这个答案创建了“之前”和“之后”标题)。
  • “-axis”文本也是如此。请注意,它可能会与您在垂直轴上书写的任何轴标签重叠。另请注意,现在我们必须将左侧的 gridspec 稍微向右移动(通过 的left参数add_gridspec)。
  • wspace也可以引入add_gridspec。我不知道为什么它在您的代码中不起作用。
  • 对于 2 个网格规范之间的空间,请使用函数中的leftright参数add_gridspec
  • top主标题和子图之间的空间可以通过add_gridspec.
  • 您的内部循环看起来非常相似,也许您可​​以定义一个函数并保存一些代码行。就我而言,我试图将所有内容都封装在一个循环中。

希望能帮助到你。

在此处输入图像描述


推荐阅读