catplot: категориальные сетки графиков в Seaborn
Одна функция catplot заменяет полдесятка категориальных графиков: переключатель kind, раскладка по сетке col и row — и сравнение групп превращается в три панели рядом.
Редакция Питоники
К категории данных Seaborn предлагает десяток функций: barplot для средних, boxplot для разброса, pointplot для трендов — и это только начало списка. У каждой свои параметры, и на маленький вопрос «а как это выглядит по городам?» ответ почему-то требует переписывать вызов заново. sns.catplot закрывает этот разнобой: catplot — одна функция с переключателем kind: bar, box или point вместо трёх отдельных вызовов. Плюс то, чего у axes-level функций нет вовсе — автоматическая раскладка в сетку.
В этом уроке разберём три рабочих значения kind, соберём сетку панелей через col и row и сформулируем правило, когда figure-level функция выигрывает у axes-level. Данные те же, что и во всём курсе: интернет-магазин, выручка по городам за четыре месяца.
catplot: одна функция вместо десяти
Сначала посмотрим на таблицу, с которой работаем весь урок: три города, четыре месяца, выручка в тысячах рублей — 12 строк.
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Москва", "Москва", "Москва",
"Казань", "Казань", "Казань", "Казань",
"Сочи", "Сочи", "Сочи", "Сочи"],
"месяц": ["янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр"],
"выручка": [412, 385, 467, 501,
254, 241, 289, 296,
187, 224, 310, 342],
})
print(df)
город месяц выручка 0 Москва янв 412 1 Москва фев 385 2 Москва мар 467 3 Москва апр 501 4 Казань янв 254 5 Казань фев 241 6 Казань мар 289 7 Казань апр 296 8 Сочи янв 187 9 Сочи фев 224 10 Сочи мар 310 11 Сочи апр 342
В данных видна история: Москва стабильна и велика, Казань стоит на месте, а Сочи разгоняется к сезону. Именно такие сюжеты удобно показывать catplot: он сам сгруппирует строки по городу, посчитает средние и нарисует. Первый вызов — со значением kind="bar":
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Москва", "Москва", "Москва",
"Казань", "Казань", "Казань", "Казань",
"Сочи", "Сочи", "Сочи", "Сочи"],
"месяц": ["янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр"],
"выручка": [412, 385, 467, 501,
254, 241, 289, 296,
187, 224, 310, 342],
})
sns.catplot(data=df, x="город", y="выручка", kind="bar")
plt.show()
График отображается под редактором
Получились столбцы средних с чёрными усами — доверительными интервалами, знакомыми по уроку про barplot. Заметно и главное отличие: мы не вызывали plt.subplots() и не передавали ax. catplot относится к figure-level функциям: он сам создаёт фигуру целиком и возвращает объект-контейнер, а не рисует в готовую панель. Подробно про контейнер — ниже, а пока поменяем kind.
kind: bar, box, point
kind — переключатель типа категориального графика. kind="box" вместо столбцов рисует ящики с усами: медиану, квартили и выбросы — всю форму распределения по каждой группе. Это то же самое, что делает sns.boxplot, только с готовой инфраструктурой сетки:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Москва", "Москва", "Москва",
"Казань", "Казань", "Казань", "Казань",
"Сочи", "Сочи", "Сочи", "Сочи"],
"месяц": ["янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр"],
"выручка": [412, 385, 467, 501,
254, 241, 289, 296,
187, 224, 310, 342],
})
sns.catplot(data=df, x="город", y="выручка", kind="box")
plt.show()
График отображается под редактором
Третье частое значение — kind="point": точки средних, соединённые линией. Столбцы хороши для сравнения размеров, а точки с линией — для тренда: рост или падение по оси читаются наклоном. Положим на ось X месяцы, а города раскрасим через hue:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Москва", "Москва", "Москва",
"Казань", "Казань", "Казань", "Казань",
"Сочи", "Сочи", "Сочи", "Сочи"],
"месяц": ["янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр"],
"выручка": [412, 385, 467, 501,
254, 241, 289, 296,
187, 224, 310, 342],
})
sns.catplot(data=df, x="месяц", y="выручка", kind="point", hue="город")
plt.show()
График отображается под редактором
Три линии — три города, и история данных видна сразу: Москва идёт ровно вверх, Казань чуть подрастает, Сочи выстреливает весной. На bar-графике тот же сюжет потребовал бы трёх групп столбцов и превратился бы в частокол. Правило выбора простое: сравниваем величины — bar; смотрим форму распределения — box; смотрим динамику по категориям — point.
col и row: сетка малых кратных
Главная способность catplot, которой нет у barplot и company, — раскладка в сетку. Параметр col="город" говорит: сделай по панели на каждое значение колонки «город» и поставь их в ряд по колонкам. Один вызов — и сравнение групп происходит взглядом слева направо:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Москва", "Москва", "Москва",
"Казань", "Казань", "Казань", "Казань",
"Сочи", "Сочи", "Сочи", "Сочи"],
"месяц": ["янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр"],
"выручка": [412, 385, 467, 501,
254, 241, 289, 296,
187, 224, 310, 342],
})
sns.catplot(
data=df,
x="месяц", y="выручка",
col="город",
kind="bar",
height=3, aspect=0.8,
)
plt.show()
График отображается под редактором
Параметры height и aspect задают размер панелей: height — высота каждой панели в дюймах, ширина получается умножением на aspect. У figure-level функций нет привычного figsize — фигуру собирает сама catplot, поэтому размер управляется именно так. Параметр row работает так же, но раскладывает панели по строкам; вместе они дают сетку col × row — об этом подробно в уроке про FacetGrid, который лежит под капотом catplot.
Что же возвращает catplot? Проверим тип и форму:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Казань", "Сочи", "Москва", "Казань", "Сочи"],
"выручка": [412, 254, 187, 467, 289, 310],
})
g = sns.catplot(data=df, x="город", y="выручка", kind="bar")
print(type(g).__name__)
print(g.axes.shape)
plt.show()
FacetGrid (1, 1)
g — это FacetGrid: контейнер сетки панелей. Без col и row сетка состоит из одной панели, поэтому форма осей — (1, 1): одна строка, одна колонка. Добавьте col="город" с тремя городами — и shape станет (1, 3). С этим объектом можно дорабатывать график после отрисовки — тема урока 18.
Когда figure-level лучше axes-level
В Seaborn два этажа API, и выбирать между ними проще по задаче:
| catplot (figure-level) | barplot, boxplot, pointplot (axes-level) | |
|---|---|---|
| Что возвращает | FacetGrid — контейнер сетки панелей | обычный ax Matplotlib |
| Сетка панелей col/row | есть, из коробки | нет — только вручную через subplots |
| Размер | height и aspect | figsize при создании фигуры |
| Встраивание в дашборд | нельзя — создаёт свою фигуру | да, через ax= |
| Когда брать | перебор видов, сравнение групп рядом | одна панель, компоновка руками |
Рабочее правило: если график один и его нужно встроить в свою композицию — axes-level функция с ax=. Если задача «покажи по каждой категории» или «перебери несколько видов» — catplot соберёт всё сам. Разбёрем финальный кадр урока: тот же point-тренд, но не наложением через hue, а сеткой по городам — каждому городу своя панель:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Москва", "Москва", "Москва",
"Казань", "Казань", "Казань", "Казань",
"Сочи", "Сочи", "Сочи", "Сочи"],
"месяц": ["янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр",
"янв", "фев", "мар", "апр"],
"выручка": [412, 385, 467, 501,
254, 241, 289, 296,
187, 224, 310, 342],
})
sns.catplot(
data=df,
x="месяц", y="выручка",
col="город",
kind="point",
height=2.8, aspect=0.9,
)
plt.show()
График отображается под редактором
Что дальше
catplot закрывает категориальный блок курса: один вызов, три вида, сетка панелей. Следующий урок — regplot: точки, линия регрессии и доверительная полоса, чтобы увидеть тренд двух числовых величин, а не групп. За ним — доводка любого из этих графиков до отчётного вида: заголовки, аннотации и сохранение в PNG.
catplot — одна функция с переключателем kind: bar, box или point вместо трёх отдельных вызовов.
Сначала предскажи ответ в голове — это главный навык программиста.
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Казань", "Сочи", "Москва", "Казань", "Сочи"],
"выручка": [412, 254, 187, 467, 289, 310],
})
g = sns.catplot(data=df, x="город", y="выручка", kind="bar")
print(type(g).__name__)
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Казань", "Сочи", "Москва", "Казань", "Сочи"],
"выручка": [412, 254, 187, 467, 289, 310],
})
print(df.groupby("город")["выручка"].mean().round(1).idxmax())
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({
"город": ["Москва", "Казань", "Сочи"] * 2,
"месяц": ["янв", "янв", "янв", "фев", "фев", "фев"],
"выручка": [412, 254, 187, 467, 289, 310],
})
g = sns.catplot(data=df, x="месяц", y="выручка", col="город", kind="bar")
print(g.axes.shape)
1. Что возвращает sns.catplot?
2. Какое значение kind нарисует точки средних, соединённые линией?
3. Что делает параметр col="город" в вызове catplot?
4. Почему вызову catplot нельзя передать параметр ax=?
5. За что отвечают height=3 и aspect=0.8 в вызове catplot?
Постройте сетку catplot по данным двух категорий товаров в трёх городах: по панели на каждый город (col="город"), столбчатый график (kind="bar"), высота панели 3 дюйма. Данные уже в заготовке.
Чем sns.catplot отличается от sns.barplot?
barplot — axes-level функция: рисует один график в готовую панель ax и возвращает её. catplot — figure-level надстройка: сама создаёт фигуру, возвращает FacetGrid и умеет раскладывать несколько панелей в сетку через col и row. kind="bar" у catplot внутри вызывает ту же логику barplot — столбцы средних с доверительными интервалами получаются одинаковыми.
Урок 18: FacetGrid — малые кратныеКак задать размер графика у catplot?
Параметрами height и aspect: height — высота каждой панели в дюймах, ширина равна height, умноженной на aspect. Например, height=3, aspect=0.8 даст панели 3 на 2.4 дюйма. Привычный figsize=(10, 4) catplot не принимает — он сам собирает фигуру, а размер сетки зависит ещё и от числа панелей.
Как задать свой порядок категорий в catplot?
Параметром order — списком значений по оси X, например order=["янв", "фев", "мар", "апр"]. Для категорий hue есть hue_order, для панелей сетки порядок задаёт col_order и row_order. Без них Seaborn берёт порядок первого появления значений в таблице.
Как добавить общий заголовок на график catplot?
Через Matplotlib-интерфейс фигуры: g = sns.catplot(...), затем g.figure.suptitle("Общий заголовок") перед plt.show(). Подписи отдельных панелей catplot расставляет сам методом set_titles — по значению категории. Доводке заголовков и аннотаций посвящён урок 17.
Урок 17: подписи, заголовки, аннотацииПонравился урок? Сошлитесь на него
«catplot — одна функция с переключателем kind: bar, box или point вместо трёх отдельных вызовов.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что читать дальше
Seaborn · Урок 14
jointplot в Seaborn: связь двух величин и распределения по краям
jointplot рисует связь двух величин в центре и их распределения по краям: сгущения и выбросы видны одновременно. kind="kde" и kind="hex" для плотных данных.
Seaborn · Урок 16
regplot: тренд и регрессия на графике рассеяния
Точки, линия регрессии и доверительная полоса одним вызовом regplot: как увидеть тренд двух величин, когда прямая врёт и что говорит наклон.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Matplotlib / Seaborn · Урок 1
Визуализация данных в Python: первое знакомство с Matplotlib
Первый график в Python за три строки кода, анатомия figure и axes, шпаргалка «какой график для каких данных» и сохранение в PNG. Всё запускается прямо на странице.
построение графиков pythonграфики python
Matplotlib / Seaborn · Урок 6
Оформление графиков: легенды, аннотации, сетки и стили Matplotlib
Легенда, аннотации со стрелками, сетка, готовые стили и rcParams — доводим график Matplotlib до презентационного уровня и сохраняем в PNG для слайдов.
оформление графиков matplotlibсетка на графике matplotlib grid
Seaborn · Урок 18
FacetGrid: малые кратные — сравнить группы рядом
Три города на одной гистограмме — каша, три гистограммы рядом — отчёт. FacetGrid: одна формула графика, сетка панелей по любой колонке таблицы.
seaborn facetgridмалые кратные