Matplotlib: построение графиков в Python от А до Я

Matplotlib: построение графиков в Python от А до Я Полезное

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

Ниже разбираю установку, два интерфейса библиотеки (быстрый pyplot и объектный API через Figure и Axes), четыре базовых типа графиков, настройку подписей и легенды и сохранение результата в файл. Все примеры кода можно скопировать и запустить.

Установка Matplotlib

Библиотека ставится одной командой через менеджер пакетов pip:

pip install matplotlib

Matplotlib работает на Windows, macOS и Linux. В Jupyter Notebook и Google Colab она обычно уже установлена, отдельная установка не нужна. Проверить, что все встало и какая версия используется, можно так:

import matplotlib
print(matplotlib.__version__)
# в консоли появится номер версии, например: 3.10.0

Практически весь код визуализации пишут не через сам пакет matplotlib, а через его модуль pyplot. Его принято импортировать под коротким псевдонимом plt — это соглашение из официальной документации:

import matplotlib.pyplot as plt

Данные для примеров можно задавать обычными списками Python. Для больших массивов и случайных выборок часто подключают NumPy (import numpy as np), но для первых графиков он не обязателен.

Два интерфейса: pyplot и объектный API (Figure и Axes)

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

Интерфейс pyplot (быстрый). Вы вызываете функции модуля: plt.plot(), plt.title(), plt.show(). Matplotlib сам держит в памяти «текущий» график и применяет команды к нему. Этот стиль пришел из MATLAB, он удобен для быстрого одиночного графика в интерактивной сессии.

Объектный API (гибкий). Вы явно создаете объекты и вызываете их методы. Стартовая строка fig, ax = plt.subplots() возвращает Figure и Axes, дальше вы работаете с ними напрямую: ax.plot(), ax.set_title(). Этот стиль рекомендуется как основной: он не зависит от «текущего» состояния и не путается, когда графиков на странице несколько.

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

Термин Что это
Figure все окно (холст) целиком; может содержать несколько Axes
Axes одна область с графиком: данные, оси, подписи; не путать с «осью»
Axis одна числовая ось — X или Y — внутри Axes

То есть Figure — это лист бумаги, Axes — нарисованный на нем график, а Axis — линейка по краю этого графика. Дальше в статье основной стиль — объектный (fig, ax), а для сравнения рядом показываю эквивалент на pyplot.

Базовые графики: line, bar, scatter, hist

Начну с минимального полного примера, который копируется и запускается. Линейный график соединяет заданные точки линией:

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]

fig, ax = plt.subplots()  # создаем Figure и одну Axes
ax.plot(x, y)             # строим линию по точкам (x, y)
plt.show()                # откроется окно с графиком (это картинка, не текст в консоли)

Результат — не вывод в консоли, а окно с линией, поднимающейся по параболе. Тот же график в стиле pyplot короче, потому что Figure и Axes создаются неявно:

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]

plt.plot(x, y)
plt.show()

Функция plt.show() выводит окно с графиком. Без нее в обычном скрипте картинка не появится; в Jupiter Notebook график рисуется прямо под ячейкой и show() часто можно не писать.

Столбчатая диаграмма (bar). Подходит для сравнения величин по категориям — например, выручки по месяцам:

import matplotlib.pyplot as plt

months = ["Янв", "Фев", "Мар", "Апр"]
revenue = [120, 90, 150, 140]

fig, ax = plt.subplots()
ax.bar(months, revenue)  # высота столбца = значение
plt.show()

Диаграмма рассеяния (scatter). Нужна, когда важна не линия, а взаимосвязь двух переменных: каждая пара значений — отдельная точка на плоскости:

import matplotlib.pyplot as plt

x = [5, 7, 8, 7, 2, 17, 2, 9]
y = [99, 86, 87, 88, 100, 86, 103, 87]

fig, ax = plt.subplots()
ax.scatter(x, y)  # рисует точки, не соединяя их линией
plt.show()

Гистограмма (hist). Показывает не отдельные значения, а их распределение: сколько значений попало в каждый интервал. Чем больше значений в диапазоне, тем выше столбик. Для наглядности возьму 1000 случайных чисел:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)  # 1000 значений вокруг среднего 0

fig, ax = plt.subplots()
ax.hist(data, bins=20)  # bins - число интервалов (столбиков)
plt.show()

Важно не путать столбчатую диаграмму и гистограмму: bar сравнивает заранее заданные значения по категориям, hist сам раскладывает набор чисел по интервалам и считает, сколько чисел в каждый попало.

Настройка графика: заголовок, подписи, легенда, сетка

Пустой график без подписей читать неудобно. Matplotlib позволяет добавить заголовок, подписи осей, легенду и сетку. Соберу все вместе на примере с двумя линиями — план и факт выручки:

import matplotlib.pyplot as plt

months = ["Янв", "Фев", "Мар", "Апр", "Май"]
plan = [100, 120, 130, 140, 150]
fact = [90, 130, 120, 150, 145]

fig, ax = plt.subplots()
ax.plot(months, plan, color="blue", label="План")
ax.plot(months, fact, color="red", label="Факт")

ax.set_title("Выручка: план и факт")   # заголовок графика
ax.set_xlabel("Месяц")                 # подпись оси X
ax.set_ylabel("Выручка, тыс. руб.")    # подпись оси Y
ax.legend()                            # легенда собирается из label
ax.grid(True)                          # включает сетку

plt.show()

Здесь color задает цвет линии, а label — ее подпись, которую потом собирает в легенду вызов ax.legend(). Две линии разного цвета с легендой сразу читаются: видно, где план, где факт.

Именно на настройке чаще всего спотыкаются те, кто копирует примеры вперемешку. В объектном API методы начинаются с set_ (ax.set_title), а в pyplot те же действия называются короче (plt.title). Сопоставлю их в таблице.

Задача pyplot (быстро) Объектный API (гибко)
Построить график plt.plot(x, y) ax.plot(x, y)
Заголовок plt.title("...") ax.set_title("...")
Подпись оси X plt.xlabel("...") ax.set_xlabel("...")
Легенда plt.legend() ax.legend()
Пределы оси X plt.xlim(0, 10) ax.set_xlim(0, 10)

Если увидели в чужом коде plt.title, а у себя пишете через ax, — нужен ax.set_title. Это не разные библиотеки, а два интерфейса одной.

Сохранение графика: savefig

Чтобы вставить график в отчет или на сайт, его сохраняют в файл методом savefig. Формат Matplotlib определяет по расширению имени файла:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])

fig.savefig("plot.png", dpi=300, bbox_inches="tight")  # сохраняет файл, окно не открывается

Параметр dpi задает разрешение для растровых форматов (PNG, JPG): чем больше, тем четче и тяжелее файл. bbox_inches="tight" обрезает лишние поля вокруг графика. Кроме PNG поддерживаются векторные форматы — plot.svg и plot.pdf: они масштабируются без потери качества и лучше подходят для печати.

Одна распространенная ловушка: если вызвать plt.savefig() уже после plt.show(), в некоторых интерактивных режимах в файл попадет пустая картинка, потому что show() освобождает текущую фигуру. Чтобы этого не случилось, либо вызывайте сохранение до show(), либо используйте метод конкретного объекта — fig.savefig(...), как в примере выше: объект fig сохраняется в памяти, и порядок вызовов перестает влиять на результат.

Выводы

Matplotlib строит графики из обычных списков или массивов чисел. Работать с ней можно двумя способами: быстрый pyplot (plt.plot, plt.title) удобен для одиночного графика, а объектный API (fig, ax = plt.subplots(), ax.plot, ax.set_title) — основной для сложных и повторно используемых фигур. Четыре базовых типа закрывают большинство задач: plot для линий, bar для сравнения категорий, scatter для взаимосвязи двух величин, hist для распределения. Заголовок, подписи осей, легенда и сетка делают график читаемым, а savefig сохраняет его в PNG, SVG или PDF.

Где применяется на практике

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

Освойте тему на практике

Системно освоить работу с данными и их визуализацию помогает курс Python для аналитики данных: от загрузки таблиц и построения графиков до готовых аналитических отчетов.

Освойте тему на практике

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

Смежные темы: Jupyter Notebook и JupyterLab: начало работы, Случайные числа в Python, MATLAB: описание и особенности.

FAQ

Чем Matplotlib отличается от Seaborn и Plotly?
Seaborn — надстройка над Matplotlib: она строит статистические графики меньшим объемом кода, но под тонкую настройку возвращается к Matplotlib. Plotly делает интерактивные графики для веба (с зумом и подсказками). Matplotlib — базовый, наиболее гибкий инструмент, на котором держатся остальные.

Почему после plt.plot() не появляется график?
В обычном скрипте нужен вызов plt.show() — без него окно не откроется. В Jupyter Notebook график рисуется под ячейкой автоматически. На сервере без экрана окна нет вовсе: там используют неинтерактивный режим и сохраняют результат в файл через savefig.

Строит ли Matplotlib трехмерные и интерактивные графики?
Трехмерные — да, через набор mpl_toolkits.mplot3d и параметр projection="3d" при создании Axes. Полноценная интерактивность (зум, всплывающие подсказки в браузере) — не сильная сторона Matplotlib; для нее чаще берут Plotly или Bokeh.

OTUS Журнал
Скидка 5% 12-19 октября на курсы (popup)
Бесплатные открытые уроки (поп-ап)