Как подготовить две альтернативные шкалы x и две альтернативные шкалы y для более чем одного субплота? - PullRequest
0 голосов
/ 29 сентября 2018

Я пытаюсь создать подзаголовок 2x2, каждый из которых состоит из двух осей x и двух осей y;первые xy соответствуют линейной шкале, а вторые xy соответствуют логарифмической шкале.Прежде чем предположить, что этот вопрос был задан ранее, в документах matplotlib и в примерах показано, как сделать несколько шкал для x или y, но не для обоих. Этот пост о stackoverflow ближе всего подходит к моему вопросу, и я попытался использовать эту идею для реализации того, что я хочу.Моя попытка ниже.

Во-первых, мы инициализируем данные, метки и метки.Идея состоит в том, что альтернативное масштабирование будет иметь одинаковые позиции тиков с измененными метками, чтобы отразить альтернативное масштабирование.

import numpy as np
import matplotlib.pyplot as plt

# xy data (global)
X = np.linspace(5, 13, 9, dtype=int)
Y = np.linspace(7, 12, 9)

# xy ticks for linear scale (global)
dtick = dict(X=X, Y=np.linspace(7, 12, 6, dtype=int))

# xy ticklabels for linear and logarithmic scales (global)
init_xt = 2**dtick['X']
dticklabel = dict(X1=dtick['X'], Y1=dtick['Y']) # linear scale
dticklabel['X2'] = ['{}'.format(init_xt[idx]) if idx % 2 == 0 else '' for idx in range(len(init_xt))] # log_2 scale
dticklabel['Y2'] = 2**dticklabel['Y1'] # log_2 scale

Заимствуя из связанного поста SO, я нарисую одно и то же на каждом из 4 вспомогательных участков,Поскольку аналогичные методы используются для обоих масштабов в каждом подплощадке, метод добавляется в цикл for.Но нам нужны номер строки, номер столбца и номер графика для каждого.

# 2x2 subplot
# fig.add_subplot(row, col, pnum); corresponding iterables = (irows, icols, iplts)
irows = (1, 1, 2, 2)
icols = (1, 2, 1, 2)
iplts = (1, 2, 1, 2)
ncolors = ('red', 'blue', 'green', 'black')

Собрав все это вместе, функция для вывода графика ниже:

def initialize_figure(irows, icols, iplts, ncolors, figsize=None):
    """ """
    fig = plt.figure(figsize=figsize)
    for row, col, pnum, color in zip(irows, icols, iplts, ncolors):
        ax1 = fig.add_subplot(row, col, pnum) # linear scale
        ax2 = fig.add_subplot(row, col, pnum, frame_on=False) # logarithmic scale ticklabels
        ax1.plot(X, Y, '-', color=color)
        # ticks in same positions
        for ax in (ax1, ax2):
            ax.set_xticks(dtick['X'])
            ax.set_yticks(dtick['Y'])
        # remove xaxis xtick_labels and labels from top row
        if row == 1:
            ax1.set_xticklabels([])
            ax2.set_xticklabels(dticklabel['X2'])
            ax1.set_xlabel('')
            ax2.set_xlabel('X2', color='gray')
        # initialize xaxis xtick_labels and labels for bottom row
        else:
            ax1.set_xticklabels(dticklabel['X1'])
            ax2.set_xticklabels([])
            ax1.set_xlabel('X1', color='black')
            ax2.set_xlabel('')
        # linear scale on left
        if col == 1:
            ax1.set_yticklabels(dticklabel['Y1'])
            ax1.set_ylabel('Y1', color='black')
            ax2.set_yticklabels([])
            ax2.set_ylabel('')
        # logarithmic scale on right
        else:
            ax1.set_yticklabels([])
            ax1.set_ylabel('')
            ax2.set_yticklabels(dticklabel['Y2'])
            ax2.set_ylabel('Y2', color='black')

        ax1.tick_params(axis='x', colors='black')
        ax1.tick_params(axis='y', colors='black')
        ax2.tick_params(axis='x', colors='gray')
        ax2.tick_params(axis='y', colors='gray')
        ax1.xaxis.tick_bottom()
        ax1.yaxis.tick_left()
        ax1.xaxis.set_label_position('top')
        ax1.yaxis.set_label_position('right')
        ax2.xaxis.tick_top()
        ax2.yaxis.tick_right()
        ax2.xaxis.set_label_position('top')
        ax2.yaxis.set_label_position('right')
        for ax in (ax1, ax2):
            ax.set_xlim([4, 14])
            ax.set_ylim([6, 13])
    fig.tight_layout()
    plt.show()
    plt.close(fig)

Вызовinitialize_figure(irows, icols, iplts, ncolors) приводит к приведенному ниже рисунку.

enter image description here

Я применяю те же xlim и ylim, поэтому я не понимаю, почему подзаговорывсе разные размеры.Кроме того, метки осей и метки осей не находятся в указанных позициях (поскольку индексирование fig.add_subplot(...) начинается с 1 вместо 0.

В чем моя ошибка и как я могу достичь желаемого результата?

(Если неясно, я пытаюсь поставить xticklabels и xlabels для линейной шкалы в нижнем ряду, xticklabels и xlabels для логарифмической шкалы нав верхнем ряду 'yticklabels and ylabels for the linear scale on the left side of the left column, and the 'yticklabels и ylabels для логарифмической шкалы с правой стороны правого столбца. color='black' kwarg соответствует линейной шкале, а color='gray' kwarg соответствуетлогарифмическая шкала.)

1 Ответ

0 голосов
/ 29 сентября 2018

Списки irows и icols в коде не служат какой-либо цели.Чтобы создать 4 вспомогательных участка в сетке 2x2, вы должны выполнить циклы по range(1,5),

for pnum in range(1,5):
    ax1 = fig.add_subplot(2, 2, pnum)

. Это может быть не единственной проблемой в коде, но если подпрограммы не созданы правильно, это не так.стоит посмотреть дальше вниз.

...