Поліпшення розміру / інтервалу субплоти за допомогою багатьох субплоттів у 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) моєю назвою subplot. Якщо хтось стикається з подібною проблемою, ось що допомогло в моєму випадку stackoverflow.com/a/45161551/11740420 . А саме rectпараметрtight_layout()
Сіяна Павлова

284

Ви можете використовувати 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
Я не бачу кнопки налаштування. Хоча я в зошиті Юпітера. Я спробував% matplotlib inline та% matplotlib notebook.
Метт Клейнсміт

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

@JohnZwinck, посилання у вашому коментарі зараз мертве.
користувач4015990

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повільніше, тому що, як видно з цієї відповіді, він оптимізує макет перед кожним кроком малювання .
ВажливістьBeingErnest

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