Линейные графики в Matplotlib: plot, цвета, стили и подписи
plt.plot() под микроскопом: цвета, маркеры, стили линий, легенды, диапазоны осей и кейс с двумя температурными кривыми за месяц.
Редакция Питоники
Синоптики дали прогноз на месяц: минимум и максимум на каждый день. Таблица из 60 чисел читается мучительно, а две линии на одном графике рассказывают всё за секунду: виден и разрыв между ночью и днём, и волны потеплений, и жара к концу месяца. Линейный график — рабочая лошадка аналитики: курсы валют, метрики продукта, температура, трафик. Сегодня разберём plt.plot() до винтика.
Как построить линейный график в Python: базовый plot
import matplotlib.pyplot as plt
# Курс доллара за 5 дней, рублей
usd = [89.1, 90.3, 90.0, 91.2, 92.5]
plt.plot(usd)
plt.show()
График отображается под редактором
Мы передали только один список — Matplotlib принял его за значения по оси Y, а по X проставил индексы: 0, 1, 2, 3, 4. Если нужен свой X — передайте два списка одинаковой длины: plt.plot(x, y).
Что происходит под капотом
plot() берёт пары точек и соединяет соседние отрезками. Никакого сглаживания: линия между двумя точками — всегда прямая. Хотите плавную кривую — давайте больше точек. Отсюда и правило: график из двух точек — это отрезок, а «красивый» график — это обычно много точек, а не особый параметр.
Вторая деталь: plot() возвращает список объектов Line2D, а не рисует сразу — отрисовка происходит в show(). Мы уже видели это в первом уроке по Matplotlib; сейчас важнее другое — один вызов plot() с одним набором данных даёт ровно одну линию.
Свой X: строки вместо чисел
Вдоль оси X не обязаны стоять числа — подойдут и строки, Matplotlib расставит их как категории. Так удобно подписывать дни, месяцы и каналы продаж:
import matplotlib.pyplot as plt
dates = ["01.07", "02.07", "03.07", "04.07", "05.07"]
usd = [89.1, 90.3, 90.0, 91.2, 92.5]
fig, ax = plt.subplots()
ax.plot(dates, usd, marker="o")
ax.set_title("Курс доллара, руб.")
ax.set_ylabel("Рублей за доллар")
plt.show()
График отображается под редактором
Ловушка здесь одна: строки не знают, что они даты, — при пропуске дня график его просто не покажет, а интервал между делениями станет неравным. Для настоящих временных рядов даты держат в pandas как datetime — а данные из DataFrame превращаются в графики без пересыпания в списки: см. раздел Pandas самоучителя.
Цвет линии, маркеры и стиль: параметры plot
Всё оформление линии задаётся именованными параметрами. Вот те, что вы будете использовать каждый день:
| Параметр | Что задаёт | Примеры значений |
|---|---|---|
| color | Цвет линии | "red", "#2E86AB", "tab:blue" |
| linestyle | Тип линии | "-" сплошная, "--" пунктир, ":" точки, "-." штрих-точка |
| marker | Маркер в точках данных | "o" круг, "s" квадрат, "^" треугольник |
| linewidth | Толщина линии в пунктах | 1 — тонкая, 2.5 — акцентная |
| markersize | Размер маркера | 6 по умолчанию, 10 — крупный |
| alpha | Прозрачность от 0 до 1 | 0.5 — полупрозрачная линия |
Цвет задаётся тремя способами: именем ("tomato"), HEX-кодом ("#2E86AB") или короткой строкой "r", "g", "b", "k". HEX — самый гибкий вариант, если нужно попасть в фирменные цвета отчёта. Стили линий несут смысл: сплошная — факт, пунктир — прогноз. Готовые палитры и целостный стиль графика — в уроке про оформление графиков.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
fig, ax = plt.subplots()
ax.plot(x, [10, 12, 11, 15, 14], color="#2E86AB", linewidth=2.5, label="hex-цвет")
ax.plot(x, [8, 9, 12, 10, 13], color="tomato", linestyle="--", label="имя цвета")
ax.legend()
plt.show()
График отображается под редактором
Здесь заодно показан приём, без которого многослойные графики теряют смысл: у каждой линии есть label, а plt.legend() собирает подписи в легенду. Задали label, но забыли legend — подписи молча не появятся.
Форматная строка: короткая запись
Третий позиционный аргумент plot — компактный код из трёх символов: цвет, маркер, стиль. "ro--" означает red, круг, пунктир. Удобно для быстрых набросков:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [4, 6, 5], "g^-") # зелёные треугольники, сплошная линия
plt.plot([1, 2, 3], [2, 3, 4], "rs:") # красные квадраты, точечная линия
plt.show()
График отображается под редактором
Несколько линий на одном графике
Вызывайте plot() несколько раз подряд — все линии лягут на одни оси. Цвета Matplotlib раздаёт сам по циклу из десяти цветов: первая линия получит tab:blue, вторая tab:orange, третья tab:green и так далее. Это спасает при двух-трёх линиях, но при шести цветной спагетти-график никто читать не будет — линии нужно подписывать легендой и выделять главную.
Кейс этого урока: температуры за июль. Минимум и максимум на каждый день — классические две линии, которые просят один холст.
import numpy as np
import matplotlib.pyplot as plt
# Синтетические температуры за июль
np.random.seed(42)
days = np.arange(1, 31)
t_max = 24 + 4 * np.sin(days / 4) + np.random.normal(0, 1, 30)
t_min = 13 + 3 * np.sin(days / 4) + np.random.normal(0, 1, 30)
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(days, t_max, color="#D62728", label="Максимум днём")
ax.plot(days, t_min, color="#1F77B4", label="Минимум ночью")
ax.set_title("Температура в июле: минимум и максимум")
ax.set_xlabel("День месяца")
ax.set_ylabel("Температура, C")
ax.legend()
ax.grid(True, alpha=0.3)
plt.show()
График отображается под редактором
Что читается мгновенно. Разрыв между линиями — суточный разброс: около десяти градусов, сужается к середине месяца. Волна на обеих линиях — циклы потеплений. Линии не пересекаются: ночи не бывают теплее дней, и если бы пересеклись, это был бы сигнал ошибки в данных. Ради такой картины таблицу и не показывают.
Выделяем главную линию: скользящее среднее
Дневные данные всегда шумят: пятницы отрываются, праздники проваливаются. Тренд тонет в зигзагах. Классический приём — наложить на сырой ряд скользящее среднее: сырые данные серым и полупрозрачно, среднее — яркой толстой линией.
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
sales = np.cumsum(np.random.normal(5, 20, 60)) + 500 # дневные продажи
window = 7
smooth = np.convolve(sales, np.ones(window) / window, mode="valid")
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(sales, color="gray", alpha=0.5, label="По дням")
ax.plot(range(window - 1, 60), smooth, color="#D62728", linewidth=2.5,
label="Среднее за 7 дней")
ax.set_title("Шум и тренд: скользящее среднее")
ax.set_xlabel("День")
ax.set_ylabel("Продажи, тыс. руб.")
ax.legend()
plt.show()
График отображается под редактором
np.convolve со скользящим окном — минимальный способ посчитать среднее без pandas. Смысл приёма шире конкретной функции: главная линия — толстая и яркая, контекст — серый и прозрачный. Глаз сам решает, что важнее, без единого слова в легенде.
Прогноз пунктиром: linestyle как смысл
Один из самых частых графиков в бизнесе — факт плюс прогноз. Приём: один цвет для связной истории, но факт сплошной линией, а прогноз — пунктиром с маркерами. Легенда и стиль линии вместе говорят: «до этой точки — измерено, после — предположение».
import matplotlib.pyplot as plt
fact_x = [1, 2, 3]
fact_y = [120, 135, 128]
forecast_x = [3, 4, 5, 6]
forecast_y = [128, 133, 140, 149]
fig, ax = plt.subplots()
ax.plot(fact_x, fact_y, color="#2E86AB", linewidth=2.5, label="Факт")
ax.plot(forecast_x, forecast_y, color="#2E86AB", linestyle="--",
marker="o", label="Прогноз")
ax.set_title("Выручка: факт и прогноз")
ax.set_xlabel("Месяц")
ax.set_ylabel("Тыс. руб.")
ax.legend()
plt.show()
График отображается под редактором
Обратите внимание на точку стыка: факт и прогноз сходятся в месяце 3 — без этого разрыв между линиями выглядит как ошибка данных. Стили линий — не украшение, а система обозначений; договоритесь о ней один раз и держитесь во всём отчёте.
Подписи осей и заголовок: xlabel, ylabel, title
График без подписей — как график без данных: непонятно, что вообще изображено. Три метода закрывают вопрос: ax.set_title() для заголовка, ax.set_xlabel() и ax.set_ylabel() для осей (в pyplot-стиле — plt.title(), plt.xlabel(), plt.ylabel()). Единственный навык, который здесь нужен, — дисциплина: подписи пишем с единицами измерения.
import matplotlib.pyplot as plt
months = ["Март", "Апр", "Май", "Июн"]
sales = [120, 135, 128, 150]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.set_title("Продажи по месяцам", fontsize=14, fontweight="bold")
ax.set_xlabel("Месяц")
ax.set_ylabel("Сумма, тыс. руб.")
plt.show()
График отображается под редактором
У заголовка и подписей есть свои параметры: fontsize, fontweight, color, позиция loc. И ещё один редакторский приём, который отличает график «на показать» от графика «в отчёт»: заголовок должен нести вывод, а не описание. «Продажи выросли на 25% за квартал» работает лучше, чем «График продаж по кварталам» — читатель сразу понимает, зачем смотреть.
- «График продаж» — пусто; «Продажи выросли на 25% за квартал» — вывод.
- «Температура» — пусто; «Вторая половина июля теплее первой на 3 градуса» — вывод.
- «Динамика курса» — пусто; «Курс доллара вырос на 3.4% за неделю» — вывод.
Наезжают подписи оси X: rotation
Длинные подписи категорий наезжают друг на друга, и ось превращается в кашу. Лечение — повернуть подписи: plt.xticks(rotation=45) наклоняет их на 45 градусов.
import matplotlib.pyplot as plt
months = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь"]
sales = [120, 135, 128, 150, 141, 160]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
plt.xticks(rotation=45) # наклоняем подписи
ax.set_title("Продажи по месяцам, тыс. руб.")
ax.set_ylabel("Тыс. руб.")
plt.show()
График отображается под редактором
Если и после поворота тесно — сокращайте подписи или переходите на горизонтальные столбцы barh: о них и о подписи значений на столбцах — в следующем уроке.
Диапазон осей: xlim, ylim и сетка
Matplotlib сам подбирает диапазон осей с небольшим запасом — и обычно это хорошо. Свой диапазон нужен в двух случаях: выровнять масштаб у нескольких графиков для честного сравнения или оставить воздух вокруг пиков. За границы отвечают ax.set_xlim() и ax.set_ylim():
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [10, 40, 35, 42], marker="o")
ax.set_xlim(0, 5) # ось X от 0 до 5
ax.set_ylim(0, 60) # ось Y от 0 до 60 — виден уровень нуля
ax.grid(True, linestyle=":", alpha=0.6)
plt.show()
График отображается под редактором
Сетка ax.grid(True) помогает глазу сверять значения с делениями; alpha=0.3–0.6 делает её ненавязчивой. В отчётах чаще всего включают сетку только по Y: ax.grid(True, axis="y") — горизонтальные направляющие читаются чище, чем клетка.
Частые ошибки и как их исправить
- X и Y разной длины: plt.plot([1, 2, 3], [5, 6]) падает с ValueError: x and y must have same first dimension. Проверьте len(x) == len(y) — чаще всего лишний или потерянный элемент.
- label задан, но plt.legend() не вызван — подписи линий не появятся. label работает только в паре с легендой.
- Десять линий на одном холсте — «спагетти». Оставьте на графике одну-две главные линии, остальные унесите на отдельные панели — приём из урока про subplots и несколько графиков.
- Подписи осей без единиц: «Выручка» вместо «Выручка, тыс. руб.» — читатель гадает, рубли это или миллионы.
Чек-лист: график готов к отправке?
Перед тем как вставлять линейный график в отчёт, прогоните его по короткому списку — он экономит больше времени, чем любая настройка из этого урока:
- Заголовок отвечает на вопрос читателя, а не описывает тип графика.
- Обе оси подписаны, у величин есть единицы измерения.
- У каждой линии есть подпись, легенда выведена и не закрывает данные.
- Цвета различимы и не спорят: главная линия акцентная, контекст приглушён.
- Диапазон осей осознанный: вы либо доверились автоматике, либо задали его сами.
Последний пункт самый коварный: автоматический диапазон удобен, но когда вы сравниваете два графика рядом, «автоматика» у каждого своя — и сравнение получается нечестным. Выравнивайте оси через set_xlim и set_ylim, как показано выше.
Что дальше
Вы умеете строить линии, красить их, ставить маркеры, подписывать оси, управлять диапазоном и собирать несколько серий на одних осях. В реальной работе данные не вписывают руками, а читают из файлов — связка read_csv и plot разобрана в гайде про график из CSV. Следующий урок — про сравнение категорий: столбчатые диаграммы plt.bar() и гистограммы plt.hist(). Продажи по регионам, план против факта, распределение цен — всё это там, в уроке про bar и hist. Весь курс — десять уроков, а маршрут целиком — самоучитель Matplotlib.
Сначала предскажи ответ в голове — это главный навык программиста.
import matplotlib.pyplot as plt
lines = plt.plot([1, 3, 5], [2, 2, 2], color="red")
print(len(lines))
import matplotlib.pyplot as plt
x = [1, 2, 3]
y = [10, 20]
plt.plot(x, y)
1. Как сделать линию пунктирной?
2. Что означает форматная строка "ro--" в plt.plot(x, y, "ro--")?
3. Линиям задан label, но подписи в легенде не появились. В чём причина?
4. Какие цвета получат первые две линии, если не указывать color?
5. Что делает ax.grid(True, axis="y")?
Даны цены на билеты за пять недель: эконом 4200, 4500, 4300, 4800, 5200; бизнес 9800, 10200, 9900, 11000, 12500 рублей. Постройте обе линии на одном графике: эконом — сплошная синяя линия с круглыми маркерами, бизнес — пунктирная красная линия. Добавьте легенду с подписями «Эконом» и «Бизнес», заголовок «Динамика цен на билеты», подписи осей и сетку.
Как поменять цвет и стиль линии графика в Matplotlib?
Параметрами plt.plot(): color="red" или color="#2E86AB" для цвета, linestyle="--" для стиля. Есть короткая запись — форматная строка: "r--" означает красный пунктир.
Как подписать оси на графике Python?
ax.set_xlabel("...") и ax.set_ylabel("...") в объектном стиле, plt.xlabel() и plt.ylabel() в pyplot-стиле. В подписи стоит включать единицы измерения: «Выручка, тыс. руб.».
Как добавить легенду matplotlib?
Дайте каждой линии label="..." при вызове plot() и один раз вызовите plt.legend(). Позицию настраивает параметр loc, например loc="upper left".
Как сделать сетку на графике matplotlib?
ax.grid(True). Полезные параметры: linestyle=":" и alpha=0.4 для ненавязчивого вида, axis="y", чтобы сетка была только по значениям Y.
Как нарисовать несколько линий на одном графике matplotlib?
Вызовите plot() несколько раз подряд — все линии лягут на одни оси, цвета возьмутся из стандартного цикла (tab:blue, tab:orange и далее). Каждой линии дайте label и один раз вызовите plt.legend(). Отдельные панели под каждую серию — это уже subplots, тема урока про несколько графиков.
Понравился урок? Сошлитесь на него
«Стили линий — не украшение, а система обозначений; договоритесь о ней один раз и держитесь во всём отчёте.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что читать дальше
Matplotlib / Seaborn · Урок 1
Визуализация данных в Python: первое знакомство с Matplotlib
Первый график в Python за три строки кода, анатомия figure и axes, шпаргалка «какой график для каких данных» и сохранение в PNG. Всё запускается прямо на странице.
Matplotlib / Seaborn · Урок 3
Столбчатые диаграммы и гистограммы в Matplotlib: bar и hist
bar и barh для сравнения категорий, hist для распределений, параметр bins, план против факта и подписи значений над столбцами.
Matplotlib / Seaborn · Урок 5
Круговые диаграммы и subplots: несколько графиков на одном полотне
pie и donut с честными границами применимости, сетка графиков через plt.subplots, общий заголовок suptitle и мини-дашборд 2 на 2 в финале.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
openpyxl · Урок 19
openpyxl и pandas: read_excel и ExcelWriter под капотом
pd.read_excel и df.to_excel всю дорогу пользуются openpyxl: разбираем связку под капотом, ExcelWriter с несколькими листами и правило выбора инструмента.
excelwriter несколько листовpandas стили excel openpyxl
openpyxl · Урок 12
Диаграммы в Excel через openpyxl: BarChart и LineChart
Собираем настоящие диаграммы Excel из кода: BarChart по продажам недели и LineChart по выручке — Reference, add_data, категории, якорь и размеры в сантиметрах.
openpyxl график по даннымopenpyxl линейный график
Matplotlib / Seaborn · Урок 6
Оформление графиков: легенды, аннотации, сетки и стили Matplotlib
Легенда, аннотации со стрелками, сетка, готовые стили и rcParams — доводим график Matplotlib до презентационного уровня и сохраняем в PNG для слайдов.
оформление графиков matplotlibлегенда matplotlib
Проверьте знания по Matplotlib / Seaborn
В челлендже — 20 задач по Matplotlib / Seaborn, по 2 из каждого урока этого раздела. Формат: фрагмент кода и четыре варианта — что напечатает. После ответа — вердикт и объяснение со ссылкой на урок-источник.
Тест по Matplotlib / Seaborn: 20 задач