5 проверенных способов контроля размеров в Matplotlib: визуализации

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Специалисты в области науки и аналитики, создающие визуализации для публикаций и отчетов.
  • Разработчики и аналитики данных, использующие Python и Matplotlib для визуализации данных.
  • Студенты и обучающиеся, желающие улучшить свои навыки в создании графиков и визуализаций.

    Создание профессиональных визуализаций с несколькими подграфиками в Matplotlib часто превращается в настоящую головоломку. Перекрывающиеся подписи осей, неравномерные отступы, странные пропорции — знакомые проблемы? Правильное управление размерами фигуры и подграфиков — это тот навык, который отличает любительскую визуализацию от профессиональной. В этой статье я раскрою 5 проверенных способов контроля размеров в Matplotlib, которые помогут вам создавать идеальные многопанельные графики для научных публикаций, бизнес-презентаций и аналитических отчётов. 🔍📊

Хотите освоить Python не только для визуализации данных, но и для создания полноценных веб-приложений? На курсе Обучение Python-разработке от Skypro вы получите все необходимые навыки — от основ языка до профессиональной разработки. Преподаватели-практики помогут вам освоить не только Matplotlib для создания впечатляющих визуализаций, но и другие ключевые библиотеки экосистемы Python. Инвестируйте в свои навыки уже сегодня!

Основы настройки размера фигуры в Matplotlib

Перед погружением в сложные техники управления подграфиками важно понять основы настройки размера фигуры в Matplotlib. Фигура (Figure) — это контейнер верхнего уровня, который включает все элементы вашей визуализации, включая подграфики, легенды и заголовки.

Размер фигуры в Matplotlib по умолчанию составляет 6.4 × 4.8 дюйма с разрешением 100 точек на дюйм (dpi). Эти значения могут не подходить для сложных визуализаций с несколькими подграфиками, поэтому их часто требуется корректировать.

Алексей Соколов, технический директор Недавно мы столкнулись с интересной проблемой — нам нужно было подготовить серию графиков для научной публикации в высокорейтинговом журнале. Требования были очень строгими: ширина фигуры не должна превышать 7 дюймов, а высота — 9 дюймов. При этом нам требовалось разместить 6 подграфиков с разной информацией.

Первая версия выглядела ужасно — оси накладывались друг на друга, подписи обрезались, а пропорции графиков искажались. Мы потратили целый день на тонкую настройку, пока не обнаружили, что можно эффективно управлять размерами фигуры напрямую. После установки корректных размеров фигуры (7×9 дюймов) и настройки соответствующего dpi (300 для печати), наши графики стали выглядеть профессионально и были приняты журналом без замечаний.

Для базовой настройки размера фигуры в Matplotlib существует несколько ключевых параметров:

  • figsize — кортеж из двух значений (ширина, высота) в дюймах
  • dpi — разрешение фигуры в точках на дюйм
  • facecolor — цвет фона фигуры
  • edgecolor — цвет границы фигуры

Рассмотрим базовый пример настройки размера фигуры:

Python
Скопировать код
import matplotlib.pyplot as plt
import numpy as np

# Создаем фигуру размером 10×6 дюймов
plt.figure(figsize=(10, 6), dpi=100)

# Генерируем данные
x = np.linspace(0, 10, 100)
y = np.sin(x)

# Строим график
plt.plot(x, y)
plt.title('Синусоида')
plt.xlabel('x')
plt.ylabel('sin(x)')

# Отображаем график
plt.show()

Важно понимать взаимосвязь между размером фигуры в дюймах (figsize) и разрешением (dpi). Если вам нужно сохранить изображение определенного размера в пикселях, используйте следующую формулу:

Размер в пикселях = figsize (в дюймах) × dpi

Параметр Значение по умолчанию Рекомендуемое значение для публикаций Рекомендуемое значение для презентаций
figsize (ширина) 6.4 дюйма 7-8 дюймов 10-12 дюймов
figsize (высота) 4.8 дюйма 5-6 дюймов 6-8 дюймов
dpi 100 300-600 100-150

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

Пошаговый план для смены профессии

Метод figure() и параметр figsize для управления размерами

Функция figure() — это основной способ создания и настройки размеров фигур в Matplotlib. Параметр figsize является одним из самых важных при работе с подграфиками, поскольку он напрямую определяет физические размеры вашей визуализации.

Существует два основных подхода к созданию фигуры с заданным размером:

Python
Скопировать код
# Подход 1: Использование plt.figure() напрямую
fig = plt.figure(figsize=(12, 8))

# Подход 2: Использование plt.subplots() с передачей параметра figsize
fig, axes = plt.subplots(2, 3, figsize=(12, 8))

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

Давайте рассмотрим более сложный пример с несколькими подграфиками и корректным заданием размера:

Python
Скопировать код
import matplotlib.pyplot as plt
import numpy as np

# Создаем фигуру с сеткой 2×2 подграфиков размером 12×10 дюймов
fig, axs = plt.subplots(2, 2, figsize=(12, 10))

# Генерируем данные
x = np.linspace(0, 10, 100)
functions = [
(np.sin, "sin(x)"),
(np.cos, "cos(x)"),
(lambda x: x**2, "x²"),
(lambda x: np.exp(x/5), "e^(x/5)")
]

# Заполняем подграфики
for i in range(2):
for j in range(2):
func, label = functions[i*2 + j]
axs[i, j].plot(x, func(x))
axs[i, j].set_title(f'График {label}')
axs[i, j].set_xlabel('x')
axs[i, j].set_ylabel(f'{label}')

# Устанавливаем отступы между подграфиками
plt.tight_layout()

plt.show()

При определении значений figsize важно учитывать несколько факторов:

  • Количество подграфиков и их расположение (сетка)
  • Наличие и размер легенд, заголовков, подписей осей
  • Соотношение сторон данных, которые вы визуализируете
  • Конечное назначение графика (экран, печать, публикация)

Иногда требуется изменить размер уже созданной фигуры. Для этого можно использовать метод setsizeinches():

Python
Скопировать код
fig, ax = plt.subplots()
# Начальный график...

# Изменяем размер фигуры после её создания
fig.set_size_inches(10, 6)
# Сохраняем с новым размером
plt.savefig('график.png', dpi=300)

Этот метод особенно полезен при программном определении оптимального размера фигуры в зависимости от содержимого или внешних условий.

Сценарий использования Рекомендуемый метод Примерные размеры
Одиночный график plt.figure(figsize=(W, H)) figsize=(8, 6)
Сетка подграфиков (2×2) plt.subplots(2, 2, figsize=(W, H)) figsize=(12, 10)
Горизонтальный ряд (1×3) plt.subplots(1, 3, figsize=(W, H)) figsize=(15, 5)
Вертикальный столбец (3×1) plt.subplots(3, 1, figsize=(W, H)) figsize=(8, 15)
Публикация в журнале plt.figure(figsize=(W, H), dpi=300) figsize=(7, 5), dpi=300

Профессиональный подход включает определение размера фигуры, исходя из целевого размера в пикселях и требуемого разрешения. Например, если вам нужно изображение 1200×900 пикселей с разрешением 100 dpi, расчет будет следующим: figsize=(1200/100, 900/100) = (12, 9) дюймов. 📐

Регулирование подграфиков с помощью subplot_adjust()

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

Метод subplot_adjust() принимает следующие параметры:

  • left — положение левого края подграфиков (от 0 до 1)
  • right — положение правого края подграфиков (от 0 до 1)
  • bottom — положение нижнего края подграфиков (от 0 до 1)
  • top — положение верхнего края подграфиков (от 0 до 1)
  • wspace — горизонтальное расстояние между подграфиками (относительное значение)
  • hspace — вертикальное расстояние между подграфиками (относительное значение)

Все параметры задаются в долях от размера всей фигуры. Например, left=0.1 означает, что левый край подграфиков находится на расстоянии 10% от левого края фигуры.

Python
Скопировать код
import matplotlib.pyplot as plt
import numpy as np

# Создаем фигуру с сеткой 2×2 подграфиков
fig, axs = plt.subplots(2, 2, figsize=(10, 8))

# Генерируем данные
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = x**2
y4 = np.exp(x/5)

# Заполняем подграфики
axs[0, 0].plot(x, y1)
axs[0, 0].set_title('Синус')
axs[0, 1].plot(x, y2)
axs[0, 1].set_title('Косинус')
axs[1, 0].plot(x, y3)
axs[1, 0].set_title('Квадратичная функция')
axs[1, 1].plot(x, y4)
axs[1, 1].set_title('Экспоненциальная функция')

# Настраиваем расположение подграфиков
plt.subplots_adjust(
left=0.1, # левый отступ
right=0.9, # правый отступ
bottom=0.1, # нижний отступ
top=0.9, # верхний отступ
wspace=0.4, # горизонтальный интервал между подграфиками
hspace=0.4 # вертикальный интервал между подграфиками
)

plt.show()

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

Первые версии выглядели непрофессионально — где-то легенды обрезались, где-то оси накладывались друг на друга. Мы перепробовали разные значения figsize, но это не решало проблему полностью.

Прорыв произошел, когда мы обратились к методу subplot_adjust(). Установив wspace=0.3 и hspace=0.4, мы смогли увеличить пространство между графиками. Дополнительно мы настроили left=0.08 и right=0.92 для максимального использования горизонтального пространства, а bottom=0.1 и top=0.9 для вертикального.

Результат превзошел ожидания — вся информация стала читаемой, графики не перекрывали друг друга, и общая компоновка выглядела профессионально и эстетично. С тех пор мы всегда используем тонкую настройку через subplot_adjust() для всех сложных визуализаций.

Иногда требуется настроить каждый подграфик индивидуально. В таких случаях можно использовать метод subplotsadjust() в сочетании с ручным созданием подграфиков через addsubplot():

Python
Скопировать код
fig = plt.figure(figsize=(12, 8))

# Создаем первый подграфик, занимающий половину высоты и всю ширину
ax1 = fig.add_subplot(2, 1, 1)
ax1.plot(x, np.sin(x))
ax1.set_title('Большой график синуса')

# Создаем два меньших подграфика в нижней половине
ax2 = fig.add_subplot(2, 2, 3)
ax2.plot(x, np.cos(x))
ax2.set_title('Косинус')

ax3 = fig.add_subplot(2, 2, 4)
ax3.plot(x, x**2)
ax3.set_title('Квадратичная функция')

# Настраиваем расположение
plt.subplots_adjust(hspace=0.3, wspace=0.3)

plt.show()

Для сложных визуализаций с разным размером подграфиков регулирование через subplot_adjust() особенно полезно. Правильная настройка параметров позволяет эффективно использовать пространство фигуры и обеспечить читаемость всех элементов. 🔧

Автоматическое размещение с применением tight_layout()

Метод tight_layout() предоставляет простое и эффективное решение для автоматического размещения подграфиков без перекрытий. Этот метод анализирует содержимое ваших подграфиков, включая подписи осей, заголовки и легенды, и автоматически настраивает отступы для предотвращения их перекрытия.

Использование tight_layout() — это самый быстрый способ избежать распространенных проблем с наложением элементов графика:

Python
Скопировать код
import matplotlib.pyplot as plt
import numpy as np

# Создаем фигуру с сеткой 2×2 подграфиков
fig, axs = plt.subplots(2, 2, figsize=(10, 8))

# Генерируем данные
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = x**2
y4 = np.exp(x/5)

# Заполняем подграфики с длинными заголовками и подписями
axs[0, 0].plot(x, y1)
axs[0, 0].set_title('Синусоидальная функция с длинным названием')
axs[0, 0].set_xlabel('Время (секунды)')
axs[0, 0].set_ylabel('Амплитуда (метры)')

axs[0, 1].plot(x, y2)
axs[0, 1].set_title('Косинусоидальная функция с ещё более длинным названием')
axs[0, 1].set_xlabel('Время (секунды)')
axs[0, 1].set_ylabel('Амплитуда (метры)')

axs[1, 0].plot(x, y3)
axs[1, 0].set_title('Квадратичная функция')
axs[1, 0].set_xlabel('Расстояние (метры)')
axs[1, 0].set_ylabel('Ускорение (м/с²)')

axs[1, 1].plot(x, y4)
axs[1, 1].set_title('Экспоненциальная функция')
axs[1, 1].set_xlabel('Время (часы)')
axs[1, 1].set_ylabel('Рост (проценты)')

# Применяем автоматическое размещение
plt.tight_layout()

plt.show()

Метод tight_layout() принимает несколько полезных параметров для тонкой настройки:

  • pad — добавляет дополнительный отступ вокруг подграфиков (в дюймах)
  • h_pad — горизонтальный отступ между подграфиками (в дюймах)
  • w_pad — вертикальный отступ между подграфиками (в дюймах)
  • rect — границы для размещения подграфиков [left, bottom, right, top] в долях от фигуры

Например, если вам нужны дополнительные отступы:

Python
Скопировать код
plt.tight_layout(pad=3.0, w_pad=1.0, h_pad=1.0)

Метод tight_layout() особенно полезен в следующих случаях:

  • Когда у вас есть длинные подписи или заголовки, которые могут перекрываться
  • При создании графиков с разными масштабами, где размер чисел на осях может существенно отличаться
  • Когда необходимо добавить легенды к нескольким подграфикам
  • При разработке интерактивных приложений, где размер графика может динамически меняться

Важно отметить, что tight_layout() имеет определенные ограничения. Он может не работать корректно в очень сложных случаях, например:

Сценарий Проблема с tight_layout() Рекомендуемое решение
Подграфики разного размера Может не оптимально распределять пространство Использовать GridSpec или constrained_layout()
Очень большое количество подграфиков Производительность может снижаться Разделить на несколько фигур или использовать ручную настройку
Подграфики с внешними легендами Может не учитывать пространство для легенд Сначала добавить все легенды, затем применить tight_layout()
Сложные многоуровневые аннотации Может не учитывать все аннотации Использовать ручную настройку через subplots_adjust()

В более новых версиях Matplotlib (начиная с 3.3.0) появился альтернативный метод — constrainedlayout(), который предлагает более гибкое решение некоторых проблем tightlayout():

Python
Скопировать код
fig, axs = plt.subplots(2, 2, figsize=(10, 8), constrained_layout=True)
# Остальной код как обычно...

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

Продвинутые техники с GridSpec для сложных компоновок

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

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

Python
Скопировать код
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np

# Создаем фигуру
fig = plt.figure(figsize=(12, 8))

# Создаем GridSpec с 3 строками и 3 столбцами
gs = gridspec.GridSpec(3, 3)

# Создаем первый подграфик, занимающий верхние 2 строки и 2 столбца
ax1 = fig.add_subplot(gs[0:2, 0:2])
ax1.plot(np.random.rand(100))
ax1.set_title('Большой график (2×2)')

# Создаем второй подграфик справа от первого
ax2 = fig.add_subplot(gs[0:2, 2])
ax2.plot(np.random.rand(100))
ax2.set_title('Вертикальный график')

# Создаем третий подграфик внизу, занимающий всю ширину
ax3 = fig.add_subplot(gs[2, :])
ax3.plot(np.random.rand(100))
ax3.set_title('Широкий график внизу')

# Применяем автоматическое размещение с учетом GridSpec
plt.tight_layout()

plt.show()

GridSpec имеет множество полезных параметров для тонкой настройки расположения подграфиков:

  • width_ratios — соотношение ширины столбцов
  • height_ratios — соотношение высоты строк
  • wspace — горизонтальное пространство между подграфиками
  • hspace — вертикальное пространство между подграфиками

Вот пример использования этих параметров:

Python
Скопировать код
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np

# Создаем фигуру
fig = plt.figure(figsize=(12, 8))

# Создаем GridSpec с неравномерными размерами ячеек
gs = gridspec.GridSpec(
2, 3,
width_ratios=[1, 2, 1], # Средний столбец в 2 раза шире
height_ratios=[2, 1], # Верхняя строка в 2 раза выше
wspace=0.3, # Горизонтальный интервал
hspace=0.3 # Вертикальный интервал
)

# Создаем подграфики
ax1 = fig.add_subplot(gs[0, 0])
ax1.set_title('(0,0)')

ax2 = fig.add_subplot(gs[0, 1:])
ax2.set_title('(0,1:3) – широкий')

ax3 = fig.add_subplot(gs[1, :2])
ax3.set_title('(1,0:2) – широкий')

ax4 = fig.add_subplot(gs[1, 2])
ax4.set_title('(1,2)')

# Заполняем графиками
for ax in [ax1, ax2, ax3, ax4]:
ax.plot(np.random.rand(10))

plt.show()

Для еще более сложных компоновок можно использовать вложенные экземпляры GridSpec, что позволяет создавать иерархические структуры подграфиков:

Python
Скопировать код
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np

# Создаем фигуру
fig = plt.figure(figsize=(12, 8))

# Создаем основной GridSpec
gs_main = gridspec.GridSpec(2, 2, figure=fig)

# Создаем вложенный GridSpec в верхнем левом углу
gs_nested = gridspec.GridSpecFromSubplotSpec(
2, 2, subplot_spec=gs_main[0, 0]
)

# Создаем подграфики во вложенном GridSpec
ax1 = fig.add_subplot(gs_nested[0, 0])
ax1.set_title('Вложенный (0,0)')

ax2 = fig.add_subplot(gs_nested[0, 1])
ax2.set_title('Вложенный (0,1)')

ax3 = fig.add_subplot(gs_nested[1, 0])
ax3.set_title('Вложенный (1,0)')

ax4 = fig.add_subplot(gs_nested[1, 1])
ax4.set_title('Вложенный (1,1)')

# Создаем обычные подграфики в оставшихся ячейках основного GridSpec
ax5 = fig.add_subplot(gs_main[0, 1])
ax5.set_title('Основной (0,1)')

ax6 = fig.add_subplot(gs_main[1, 0])
ax6.set_title('Основной (1,0)')

ax7 = fig.add_subplot(gs_main[1, 1])
ax7.set_title('Основной (1,1)')

# Заполняем графиками
for ax in [ax1, ax2, ax3, ax4, ax5, ax6, ax7]:
ax.plot(np.random.rand(10))

plt.tight_layout()
plt.show()

GridSpec идеально подходит для создания информационных панелей, научных публикаций и отчетов, где требуется гибкое и точное размещение различных визуализаций. В сочетании с методами настройки размера фигуры, он предоставляет полный контроль над визуальным представлением ваших данных. 📊🎨

Настройка размера фигуры и подграфиков в Matplotlib — это искусство, требующее понимания как технических аспектов библиотеки, так и принципов визуального дизайна. Мы рассмотрели пять мощных методов от базового управления через figsize до сложных компоновок с GridSpec, которые позволяют создавать профессиональные и информативные визуализации. Помните, что правильно настроенный график должен не только точно передавать данные, но и делать это в удобном для восприятия виде. Экспериментируйте с разными подходами, чтобы найти оптимальное решение для конкретной задачи, и ваши визуализации всегда будут выглядеть профессионально.

Загрузка...