matplotlib有奇数个子图

bal*_*day 7 matplotlib python-2.7

我正在尝试创建一个绘图函数,该函数将所需绘图的数量作为输入并使用pylab.subplotssharex=True选项绘制它们.如果所需图的数量是奇数,那么我想删除最后一个面板并强制它上面的面板上的刻度标签.我找不到这样做的方法并同时使用该sharex=True选项.子图的数量可能非常大(> 20).

这是示例代码.在这个例子中,我想在何时强制xtick标签i=3.

import numpy as np
import matplotlib.pylab as plt

def main():
    n = 5
    nx = 100
    x = np.arange(nx)
    if n % 2 == 0:
        f, axs = plt.subplots(n/2, 2, sharex=True)
    else:
        f, axs = plt.subplots(n/2+1, 2, sharex=True)
    for i in range(n):
        y = np.random.rand(nx)
        if i % 2 == 0:
            axs[i/2, 0].plot(x, y, '-', label='plot '+str(i+1))
            axs[i/2, 0].legend()
        else:
            axs[i/2, 1].plot(x, y, '-', label='plot '+str(i+1))
            axs[i/2, 1].legend()
    if n % 2 != 0:
        f.delaxes(axs[i/2, 1])
    f.show()


if __name__ == "__main__":
     main()
Run Code Online (Sandbox Code Playgroud)

Pri*_*mer 8

如果你用if你的main函数替换最后一个:

if n % 2 != 0:
    for l in axs[i/2-1,1].get_xaxis().get_majorticklabels():
        l.set_visible(True)
    f.delaxes(axs[i/2, 1])

f.show()
Run Code Online (Sandbox Code Playgroud)

它应该做的伎俩:

情节


Dan*_*she 6

简单地说,您可以让子图要求一个偶数(在这种情况下为6个图):

f, ax = plt.subplots(3, 2, figsize=(12, 15))
Run Code Online (Sandbox Code Playgroud)

然后,删除不需要的一个:

f.delaxes(ax[2,1]) #The indexing is zero-based here
Run Code Online (Sandbox Code Playgroud)

这个问题和答案正在以一种自动化的方式进行研究,但我认为值得在此处发布基本用例。


can*_*ine 5

我一直生成任意数量的子图(有时数据会导致 3 个子图,有时是 13 个,等等)。我写了一个小实用函数来停止思考它。

我定义的两个函数如下。您可以更改风格选择以符合您的喜好。

import math
import numpy as np
from matplotlib import pyplot as plt


def choose_subplot_dimensions(k):
    if k < 4:
        return k, 1
    elif k < 11:
        return math.ceil(k/2), 2
    else:
        # I've chosen to have a maximum of 3 columns
        return math.ceil(k/3), 3


def generate_subplots(k, row_wise=False):
    nrow, ncol = choose_subplot_dimensions(k)
    # Choose your share X and share Y parameters as you wish:
    figure, axes = plt.subplots(nrow, ncol,
                                sharex=True,
                                sharey=False)

    # Check if it's an array. If there's only one plot, it's just an Axes obj
    if not isinstance(axes, np.ndarray):
        return figure, [axes]
    else:
        # Choose the traversal you'd like: 'F' is col-wise, 'C' is row-wise
        axes = axes.flatten(order=('C' if row_wise else 'F'))

        # Delete any unused axes from the figure, so that they don't show
        # blank x- and y-axis lines
        for idx, ax in enumerate(axes[k:]):
            figure.delaxes(ax)

            # Turn ticks on for the last ax in each column, wherever it lands
            idx_to_turn_on_ticks = idx + k - ncol if row_wise else idx + k - 1
            for tk in axes[idx_to_turn_on_ticks].get_xticklabels():
                tk.set_visible(True)

        axes = axes[:k]
        return figure, axes
Run Code Online (Sandbox Code Playgroud)

这是 13 个子图的示例用法:

x_variable = list(range(-5, 6))
parameters = list(range(0, 13))

figure, axes = generate_subplots(len(parameters), row_wise=True)
for parameter, ax in zip(parameters, axes):
    ax.plot(x_variable, [x**parameter for x in x_variable])
    ax.set_title(label="y=x^{}".format(parameter))

plt.tight_layout()
plt.show()
Run Code Online (Sandbox Code Playgroud)

产生以下结果:

在此处输入图片说明

或者,切换到按列遍历顺序 ( generate_subplots(..., row_wise=False)) 会生成:

在此处输入图片说明