Matplotlib для научной визуализации

Расчёт не закончен, пока результат не показан. Matplotlib — стандарт научной графики в Python, от простого графика до иллюстрации в Nature.

Matplotlib — библиотека построения графиков, фактический стандарт научной визуализации в Python; на ней строятся почти все остальные графические пакеты.

Зачем учёному графики

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

Анатомия графика Matplotlib

Ключ к Matplotlib — понять его иерархию объектов:

Figure  (весь холст, "лист бумаги")
  └── Axes  (одна система координат, "график")
        ├── Axis X, Axis Y  (оси с делениями и подписями)
        ├── Line / Scatter / Bar  (сами данные)
        ├── Title, Labels  (заголовок, подписи осей)
        └── Legend  (легенда)

Один Figure может содержать НЕСКОЛЬКО Axes (сетка подграфиков).

Эта структура важна: Figure — лист, Axes — один график на нём, и их может быть много (панель из подграфиков для статьи).

Типичный научный график

Код для чтения (Matplotlib в браузере не исполняется):

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 200)

fig, ax = plt.subplots()             # создаём Figure и одни Axes
ax.plot(x, np.sin(x), label="sin")
ax.plot(x, np.cos(x), "--", label="cos")
ax.set_xlabel("угол, рад")
ax.set_ylabel("значение")
ax.set_title("Тригонометрические функции")
ax.legend()
ax.grid(True)
plt.savefig("plot.png", dpi=300)     # для статьи — высокое разрешение

Готовим данные для графика «руками»

Прежде чем строить, данные надо вычислить. Соберём точки синусоиды на чистом stdlib — ровно те массивы, что ушли бы в ax.plot:

import math

n = 9
xs = [i * (2 * math.pi) / (n - 1) for i in range(n)]
ys = [round(math.sin(x), 3) for x in xs]

print("x (рад):", [round(x, 2) for x in xs])
print("sin(x) :", ys)
# простая ASCII-визуализация: высота столбика ~ sin
for x, y in zip(xs, ys):
    bar = "#" * int((y + 1) * 10)     # сдвиг, чтобы не было отрицательных
    print(f"{x:4.1f} | {bar}")

Вывод:

x (рад): [0.0, 0.79, 1.57, 2.36, 3.14, 3.93, 4.71, 5.5, 6.28]
sin(x) : [0.0, 0.707, 1.0, 0.707, 0.0, -0.707, -1.0, -0.707, -0.0]
 0.0 | ##########
 0.8 | #################
 1.6 | ####################
 2.4 | #################
 3.1 | ##########
 3.9 | ##
 4.7 |
 5.5 | ##
 6.3 | ##########

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

Специфика научной графики

ЭлементЗачем в науке
Планки погрешностей (errorbar)показать неопределённость измерений — обязательно
Лог-шкаладанные на много порядков (от 10⁰ до 10⁶)
Подписи с единицами«скорость, м/с» — без единиц график бессмыслен
Высокий DPI / вектор (PDF, SVG)чёткая печать в журнале

Как работает под капотом

Matplotlib разделён на два слоя. Frontend — это объекты Figure, Axes, Line2D, которые вы создаёте. Backend — движок отрисовки, превращающий эти объекты в пиксели (Agg для PNG), вектор (PDF/SVG) или интерактивное окно. Один и тот же код рисует и картинку для статьи, и интерактивный график в Jupyter — меняется лишь backend. Поэтому Matplotlib и стал стандартом: на его frontend опираются seaborn, pandas .plot() и др., а backend обеспечивает вывод куда угодно.

Частые ошибки

  • График без подписей осей и единиц. В науке это непростительно — читатель не поймёт, что показано.
  • Растровый формат для печати. Для статьи сохраняйте в PDF/SVG (вектор) или PNG с высоким DPI, иначе всё «замылится».
  • Забыть планки погрешностей. Точка без оценки неопределённости в научном графике вводит в заблуждение.

Итог

  • Matplotlib — стандарт научной графики; иерархия Figure → Axes → данные.
  • Научная графика требует подписей с единицами, планок погрешностей, лог-шкал, векторного вывода.
  • Данные для графика вычисляются заранее (numpy/stdlib), потом передаются в plot.
  • Разделение frontend/backend позволяет одним кодом рисовать в файл и в окно.
Проверьте себя
1. Какова иерархия объектов в Matplotlib?
APlot → Graph → Data
BFigure (холст) → Axes (один график) → данные (линии, точки); один Figure может содержать много Axes
CТолько один объект Plot
DCanvas → Pixel
2. Что обязательно для научного графика, но часто не нужно для делового?
AЯркие цвета
BПланки погрешностей, подписи осей с единицами измерения и при необходимости лог-шкала
C3D-эффекты
DАнимация
3. Зачем Matplotlib разделён на frontend и backend?
AДля красоты кода
BFrontend создаёт объекты графика, а сменный backend рендерит их в PNG/PDF/окно — один код, много форматов вывода
CЧтобы ускорить вычисления
DЭто требование Python