Улучшите размер / интервал подплотов с помощью большого количества субплотов в matplotlib


313

Очень похоже на этот вопрос, но с той разницей, что моя фигура может быть настолько большой, насколько это необходимо.

Мне нужно создать целую кучу вертикально сложенных графиков в matplotlib. Результат будет сохранен с помощью функции figsave и просмотрен на веб-странице, поэтому мне все равно, каков будет конечный размер изображения, если субплоты расположены так, чтобы они не перекрывались.

Независимо от того, насколько большой я позволю фигуре быть, участки всегда, кажется, пересекаются.

Мой код в настоящее время выглядит как

import matplotlib.pyplot as plt
import my_other_module

titles, x_lists, y_lists = my_other_module.get_data()

fig = plt.figure(figsize=(10,60))
for i, y_list in enumerate(y_lists):
    plt.subplot(len(titles), 1, i)
    plt.xlabel("Some X label")
    plt.ylabel("Some Y label")
    plt.title(titles[i])
    plt.plot(x_lists[i],y_list)
fig.savefig('out.png', dpi=100)

Ответы:


413

Попробуйте использовать plt.tight_layout

В качестве быстрого примера:

import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=4, ncols=4)
fig.tight_layout() # Or equivalently,  "plt.tight_layout()"

plt.show()

Без плотной компоновки

введите описание изображения здесь


С плотной компоновкой введите описание изображения здесь


21
Было бы немного яснее, если бы вы показали, что должны выполнить это после кода вашего графика, но прямо перед show ()
pyj

5
tight_layout()ударил и пропустил. Я пытался понять, что отличается, когда это не имеет никакого эффекта (остаются большие поля между сюжетами) - что часто
Джавадба

3
Это сработало очень хорошо для меня, за исключением того, что я наложил заголовок моей фигуры ( suptitle) на заголовок моего участка. В случае, если кто-то сталкивается с подобной проблемой, вот что помогло в моем случае stackoverflow.com/a/45161551/11740420 . А именно, rectпараметрtight_layout()
Сияна Павлова

285

Вы можете использовать, plt.subplots_adjustчтобы изменить интервал между участками (источник)

подпись звонка:

subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)

Значения параметров (и предлагаемые значения по умолчанию):

left  = 0.125  # the left side of the subplots of the figure
right = 0.9    # the right side of the subplots of the figure
bottom = 0.1   # the bottom of the subplots of the figure
top = 0.9      # the top of the subplots of the figure
wspace = 0.2   # the amount of width reserved for blank space between subplots
hspace = 0.2   # the amount of height reserved for white space between subplots

Фактические значения по умолчанию контролируются файлом rc


3
Я пробовал возиться с hspace, но при его увеличении кажется, что все графики уменьшаются без решения проблемы перекрытия. Я также попытался поиграть с другими параметрами, но я не знаю, что на самом деле указывает левый, правый, нижний и верхний.
mcstrother

52
@mcstrother вы можете в интерактивном режиме изменить все 6 из этих параметров, если вы нажмете кнопку «корректировки» после показа графика, а затем скопируете их в код, как только найдете то, что работает.
Ник Т

1
Я не вижу кнопку регулировки. Хотя я в тетради Jupyter. Я попробовал встроенный% matplotlib и блокнот% matplotlib.
Мэтт Кляйнсмит

1
@MattKleinsmith: кнопка настройки имеет всплывающий текст «Настроить подзаголовки» и появляется при обычном использовании Matplotlib без использования ноутбука. Это кнопка слева от кнопки сохранения «дискеты» здесь: pythonspot-9329.kxcdn.com/wp-content/uploads/2016/07/… - обратите внимание, что кнопка выглядит по-разному в зависимости от того, какую оконную систему вы используете используя, но это всегда слева от кнопки сохранения.
Джон Цвинк

@JohnZwinck, ссылка в вашем комментарии сейчас не работает.
user4015990

56

Я обнаружил, что subplots_adjust (hspace = 0.001) - это то, что мне помогло. Когда я использую пробел = Нет, между каждым графиком все еще остается пробел. Установка этого значения очень близко к нулю, однако, кажется, заставляет их выстраиваться. То, что я загрузил здесь, не самый элегантный кусок кода, но вы можете увидеть, как работает hspace.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tic

fig = plt.figure()

x = np.arange(100)
y = 3.*np.sin(x*2.*np.pi/100.)

for i in range(5):
    temp = 510 + i
    ax = plt.subplot(temp)
    plt.plot(x,y)
    plt.subplots_adjust(hspace = .001)
    temp = tic.MaxNLocator(3)
    ax.yaxis.set_major_locator(temp)
    ax.set_xticklabels(())
    ax.title.set_visible(False)

plt.show()

введите описание изображения здесь


31
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10,60))
plt.subplots_adjust( ... )

Метод plt.subplots_adjust :

def subplots_adjust(*args, **kwargs):
    """
    call signature::

      subplots_adjust(left=None, bottom=None, right=None, top=None,
                      wspace=None, hspace=None)

    Tune the subplot layout via the
    :class:`matplotlib.figure.SubplotParams` mechanism.  The parameter
    meanings (and suggested defaults) are::

      left  = 0.125  # the left side of the subplots of the figure
      right = 0.9    # the right side of the subplots of the figure
      bottom = 0.1   # the bottom of the subplots of the figure
      top = 0.9      # the top of the subplots of the figure
      wspace = 0.2   # the amount of width reserved for blank space between subplots
      hspace = 0.2   # the amount of height reserved for white space between subplots

    The actual defaults are controlled by the rc file
    """
    fig = gcf()
    fig.subplots_adjust(*args, **kwargs)
    draw_if_interactive()

или

fig = plt.figure(figsize=(10,60))
fig.subplots_adjust( ... )

Размер картины имеет значение.

«Я пробовал возиться с hspace, но при его увеличении кажется, что все графики уменьшаются без решения проблемы перекрытия».

Таким образом, чтобы создать больше пустого пространства и сохранить размер вспомогательного участка, общее изображение должно быть больше.


2
Размер изображения имеет значение, больший размер изображения может решить эту проблему! набор plt.figure(figsize=(10, 7)), размер изображения будет 2000 x 1400пикс
Belter


20

Похожий на tight_layoutmatplotlib сейчас (начиная с версии 2.2) constrained_layout. В отличие от того tight_layout, что может быть вызвано в любое время в коде для одного оптимизированного макета,constrained_layout вызвано в это свойство, которое может быть активным и будет оптимизировать макет перед каждым шагом рисования.

Следовательно, его необходимо активировать до или во время создания подзаговора, например, figure(constrained_layout=True)илиsubplots(constrained_layout=True) .

Пример:

import matplotlib.pyplot as plt

fig, axes = plt.subplots(4,4, constrained_layout=True)

plt.show()

введите описание изображения здесь

constrained_layout также может быть установлен через rcParams

plt.rcParams['figure.constrained_layout.use'] = True

Ознакомьтесь с новой записью и руководством по ограниченному макету.


1
собираюсь попробовать это: не видел этого варианта - и tight_layoutненадежен
javadba

это звучало многообещающе, но не давало достаточно места (метки осей и заголовки все еще накладывались), и рендеринг занял гораздо больше времени. tight_layout()работал лучше
Craq

2
@craq Правильно, как правило contrained_layout, медленнее, потому что, как видно из этого ответа, он оптимизирует макет перед каждым шагом рисования .
Важное значение

для меня это был самый полезный ответ - для меня тугое_положение всегда улучшает интервал по вертикали, чтобы оставить место для заголовка панели, но за счет обрезания метки оси y каждый раз. Это, напротив, работает отлично, спасибо.
Адриан Томпкинс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.