Графики Matplotlib
Беглый справочник для читателя, не знакомого с Python. Полностью тема рассматривается в основных главах книги; в печатное издание приложение не вошло.
Matplotlib является библиотекой для построения графиков. Ниже рассматривается минимум по модулю matplotlib.pyplot, системе построения графиков, аналогичной MATLAB. Подробное рассмотрение визуализации на Python (Matplotlib, Plotly, HoloViews) приведено в главе «Визуализация на Python».
import numpy as np
import matplotlib.pyplot as plt
Команда IPython, включающая отображение графиков в блокноте:
%matplotlib inline
Построение графиков
Основной функцией matplotlib является plot, строящая графики двумерных данных:
# Вычисляем координаты x и y точек на синусоиде
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
# Строим график с помощью matplotlib
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x1142b94d0>]

Несколько кривых одновременно, с заголовком, легендой и подписями осей:
y_sin = np.sin(x)
y_cos = np.cos(x)
# Строим оба графика с помощью matplotlib
plt.plot(x, y_sin)
plt.plot(x, y_cos)
plt.xlabel('x axis label')
plt.ylabel('y axis label')
plt.title('Sine and Cosine')
plt.legend(['Sine', 'Cosine'])
<matplotlib.legend.Legend at 0x114390a50>

В физике график без подписанных осей графиком не считается. На осях всегда должны быть указаны величина и её единицы измерения («t, с», «U, мВ»); за это отвечают plt.xlabel и plt.ylabel. Заголовок задаётся функцией plt.title, а plt.legend выводит легенду со списком кривых и их названий.
Имя кривой удобнее задавать непосредственно в plot через аргумент label: в этом случае plt.legend() вызывается без аргументов, и соответствие кривых и подписей не нарушается. Координатная сетка plt.grid(True) облегчает считывание значений с графика.
plt.plot(x, y_sin, label='sin(x)')
plt.plot(x, y_cos, '--', label='cos(x)') # '--' — штриховая линия
plt.xlabel('x, рад')
plt.ylabel('f(x)')
plt.title('Тригонометрические функции')
plt.legend() # имена кривых возьмутся из label
plt.grid(True) # координатная сетка
Subplots
Функция subplot размещает несколько графиков на одном рисунке:
# Вычисляем координаты x и y точек на синусоиде и косинусоиде
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# Задаём сетку subplot'ов высотой 2 и шириной 1
# и делаем активным первый subplot.
plt.subplot(2, 1, 1)
# Строим первый график
plt.plot(x, y_sin)
plt.title('Sine')
# Делаем активным второй subplot и строим второй график.
plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title('Cosine')
# Показываем рисунок.
plt.show()

Подробнее о функции subplot — в документации.
Гистограммы
Гистограмма строится первой, когда имеется набор повторных измерений: она показывает распределение значений. Сгенерируем 10 000 «измерений», рассеянных вокруг истинного значения по закону Гаусса, и рассмотрим их с помощью plt.hist.
# 10000 «измерений»: истинное значение 5.0, случайный шум 0.5
values = np.random.normal(loc=5.0, scale=0.5, size=10000)
plt.hist(values, bins=50, density=True, alpha=0.7)
plt.xlabel('Измеренное значение')
plt.ylabel('Плотность вероятности')
plt.grid(True)
Аргумент bins задаёт число корзин: при слишком малом значении распределение теряет детали, при слишком большом гистограмма становится шумной. Флаг density=True нормирует гистограмму на единичную площадь, и в этих осях её можно сравнивать с теоретической плотностью вероятности, например с гауссианой. Полупрозрачность alpha необходима, когда несколько распределений накладываются друг на друга.
Точки с погрешностями (errorbar)
Основным графиком в экспериментальной физике являются точки с погрешностями. Его строит plt.errorbar: кроме координат точек она принимает величины ошибок по осям (yerr и xerr) и рисует усы.
# «Эксперимент»: период маятника в зависимости от длины подвеса
L = np.array([0.2, 0.4, 0.6, 0.8, 1.0]) # длина, м
T = 2 * np.pi * np.sqrt(L / 9.81) # теоретический период, с
T_exp = T + np.random.normal(0, 0.03, T.size) # «измеренный» период, с
T_err = np.full_like(T, 0.05) # погрешность измерения, с
plt.errorbar(L, T_exp, yerr=T_err, fmt='o', capsize=3, label='эксперимент')
plt.plot(L, T, '--', label='теория')
plt.xlabel('L, м')
plt.ylabel('T, с')
plt.legend()
plt.grid(True)
Ключ fmt='o' необходим, поскольку экспериментальные точки изображаются маркерами и не соединяются ломаной; рядом проводится теоретическая кривая или аппроксимация. Аргумент capsize задаёт размер шляпок на концах усов, а xerr добавляет горизонтальные усы, если погрешность имеется и по оси x.
Сохранение рисунка в файл
Графики существуют внутри блокнота. Для вставки рисунка в отчёт или статью его сохраняют в файл с помощью plt.savefig; формат определяется расширением имени файла.
plt.plot(x, np.sin(x))
plt.savefig('sine.png', dpi=300, bbox_inches='tight') # растровый формат
plt.savefig('sine.pdf') # векторный формат
PNG является растровым форматом, поэтому для печати необходимо задавать разрешение dpi=300 или выше. PDF и SVG — векторные форматы, не теряющие чёткости при любом увеличении; для статей и дипломов (особенно в LaTeX) предпочтителен pdf. Аргумент bbox_inches='tight' обрезает лишние белые поля вокруг рисунка. В скриптах savefig необходимо вызывать до plt.show(): после показа фигура очищается, и в файл записывается пустой лист.
Полезные ссылки
- в официальной документации Matplotlib удобно начать с раздела Tutorials;
- Галерея примеров — сотни готовых графиков с исходным кодом; зачастую проще найти похожий пример, чем писать с нуля;
- Официальные шпаргалки (cheatsheets) укладывают всю библиотеку на пару страниц;
- Anatomy of a figure показывает, из каких частей состоит рисунок matplotlib и как эти части называются;
- Scientific Visualization: Python + Matplotlib, бесплатная книга Николя Ружье о научной визуализации.