Matplotlib

Matplotlib — стандартная библиотека графиков Python: от простых линий до сложных многопанельных рисунков с собственным стилем.

Уровень: начальный 18 разделов ⏱ 3 часа

1. Что такое Matplotlib

Matplotlib рисует графики в векторном стиле через объекты Figure и Axes. На нём строятся другие визуализации — например, статистические Seaborn.

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

2. Установка

pip install matplotlib
import matplotlib.pyplot as plt

3. Первый график

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 4, 1, 7, 3]

plt.plot(x, y, marker='o')
plt.title('Мой график')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
Традиционно сначала вызывается plt.plot, потом plt.show() — но для точного контроля лучше связка Figure/Axes из раздела 7.

4. Типы графиков

plt.scatter(x, y)                    # точки
plt.bar(['a', 'b', 'c'], [3, 8, 5])  # столбцы
plt.hist(data, bins=20)              # гистограмма
plt.plot(x, y)                       # линия
plt.fill_between(x, y, y2)           # заливка

Данные обычно берутся из Pandas: plt.plot(df['date'], df['sales']).

5. Параметры линий и точек

plt.plot(x, y,
    color='red',
    linestyle='--',
    linewidth=2,
    marker='s',
    markersize=8,
    label='Ряд 1')
plt.legend()

Цвета: hex (#ffaa00), имена ('red'), шорткоды ('r').

6. Сетки, легенды и подписи

plt.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()          # подогнать отступы
plt.savefig('plot.png', dpi=200, bbox_inches='tight')

7. Figure и Axes

Современный стиль — явные объекты:

fig, ax = plt.subplots(1, 2, figsize=(12, 4))

ax[0].plot(x, y)
ax[0].set_title('Линия')

ax[1].bar(['a', 'b'], [3, 8])
ax[1].set_title('Столбцы')

plt.show()
Явный подход (fig/ax) надёжен: вы контролируете панели, размеры и общие элементы без магии глобального состояния.

8. Несколько панелей и вложенные

fig = plt.figure(figsize=(8, 6))
gs = fig.add_gridspec(2, 2)
ax1 = fig.add_subplot(gs[0, :])   # верхняя широкая
ax2 = fig.add_subplot(gs[1, 0])   # низ-лево
ax3 = fig.add_subplot(gs[1, 1])   # низ-право

Общий заголовок: fig.suptitle('Общий').

9. Стили и настройка внешнего вида

plt.style.use('seaborn-v0_8-darkgrid')
plt.style.available   # список стилей
plt.rcParams['figure.figsize'] = (10, 5)

Палитры и шрифты настраиваются в plt.rcParams один раз в начале тетради.

10. Экспорт и ошибки

Проверяй, что русские подписи не превратились в «квадратики»: включи шрифт DejaVu Sans (по умолчанию) или установи окружение с корректными шрифтами на слабой системе.

11. Аннотации и текстовые выноски

Несколько строк кода превращают график в поясняющий слайд: стрелки, подписи точек и опорные линии:

fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
ax.annotate("пик", xy=(3, 9), xytext=(2, 8),
            arrowprops=dict(arrowstyle="->"))
ax.text(1.5, 5, "рост")
ax.axhline(4, ls="--", color="gray")
Для горизонтального выравнивания используй ha/va: ax.text(x, y, "label", ha="center", va="top") ставит подпись точно в точку.

12. Логарифмические и полярные шкалы

Данные с большим разбросом читаются лучше на логарифмической шкале, а циклические величины — в полярных координатах:

ax.set_xscale("log")
ax.set_yscale("log")

import numpy as np
theta = np.linspace(0, 2 * np.pi, 200)
ax2 = plt.subplot(projection="polar")
ax2.plot(theta, 1 + np.sin(theta))

Трёхмерные сцены подключаются отдельным модулем mpl_toolkits.mplot3d, а проекции Meshes позволяют строить topo-поверхности и гистограммы в 3D.

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

13. Анимации: FuncAnimation

Matplotlib умеет записывать GIF и видео: кадр за кадром обновляется содержимое осей, а результат собирается в файл:

from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()
x = np.linspace(0, 2 * np.pi, 200)
line, = ax.plot(x, np.sin(x))

def update(frame):
    line.set_ydata(np.sin(x + frame / 10))
    return line,

anim = FuncAnimation(fig, update, frames=100, interval=30)
anim.save("wave.gif", writer="pillow")

В Jupyter тетрадь рендерит анимацию встроенно через HTML(anim.to_jshtml()) или в протоколе %matplotlib notebook.

14. Бэкенды и интерактивность

Backend — это среда вывода: холст на дисплее, файл без GUI или встроенный рендер тетради. Выбор задаётся до импорта pyplot:

import matplotlib
matplotlib.use("Agg")   # серверный рендер в файлы без окна
import matplotlib.pyplot as plt

Интерактивность дают события холста: fig.canvas.mpl_connect("button_press_event", handler) обрабатывает клики и наведение.

На сервере без дисплея не вызывай plt.show() — процесс повиснет. Используй только savefig и закрывай фигуры через plt.close(fig).

15. Датасеты и предподготовка данных

Matplotlib сам данные не «подтягивает», но тесно работает с Pandas — это самый распространённый связок в примерах курса. Данные приходят с пропусками, типами или дубликатами, прежде чем попасть на график:

import pandas as pd
df = pd.read_csv("sales.csv")
df["date"] = pd.to_datetime(df["date"])
df = df.dropna(subset=["amount"])
Прежде чем рисовать график, изучи распределение данных: гистограмма df["x"].hist(bins=30) сразу покажет выбросы, с которыми график будет выглядеть бесполезным.

16. Оси времени: даты и интервалы

Временные ряды — самый частый тип данных: продажи по дням, температура по часам. Matplotlib понимает datetime и сам расставляет подписи, если отдать ему даты:

import matplotlib.dates as mdates
ax.plot(df["date"], df["amount"])
ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %Y"))
plt.xticks(rotation=45)
Для неравномерных данных (дни без продаж) ставь точки-маркеры поверх линии — иначе читатель «дорисует» непрерывный тренд там, где его не было.

17. Производительность: большие данные

Когда точек становится 100 000+, стандартный plot тормозит: каждая точка — отдельный объект. Для больших объёмов используют растеризацию и агрегацию:

ax.plot(x, y, linewidth=0, marker=".", markersize=1, rasterized=True)
from matplotlib.collections import LineCollection
Не привыкай «просто по-мельче точки» — при 10 М точек упадёт память, а отчёт станет невозможным. Стремись к rasterized только на слое графика, а не на всём полотне.

18. Автоматические отчёты: циклы и PDF

Регулярные отчёты генерируются скриптом: каждый график в свою секцию, все — в один общий файл. Это снимает ручную «перерисовку» после каждого обновления данных:

from matplotlib.backends.backend_pdf import PdfPages
with PdfPages("report.pdf") as pdf:
    for key, sub in df.groupby("region"):
        fig, ax = plt.subplots(figsize=(6, 4))
        ax.plot(sub["date"], sub["amount"])
        ax.set_title(f"Регион {key}")
        pdf.savefig(fig); plt.close(fig)
Держи настройки отчёта (цвета, заголовки, лого) в одном конфиге: глобальные стили rcParams делают все графики единообразными в рамках сессии.

Что дальше

Для статистических графиков поверх Matplotlib используй Seaborn, а данные готовь в Pandas.

← Вернуться к курсам