barplot в Seaborn: средние по категориям с интервалами
sns.barplot усредняет числовой столбец по категориям и добавляет усики доверительного интервала. Сравниваем выручку магазинов в четырёх городах и наводим порядок через order.
Редакция Питоники
У сети из четырёх магазинов — по три месячных отчёта на город. Вопрос директора простой: где выручка выше и можно ли ей верить? В Matplotlib ответ собирался в два хода: сначала groupby().mean() в pandas, потом plt.bar по результату. Seaborn делает это одной строкой — и заодно честно показывает, насколько каждому среднему можно верить.
Урок разбирает sns.barplot по косточкам: что такое усики над столбцами, почему высота — это среднее, а не сумма, и как параметр order наводит порядок в столбцах.
Данные: выручка по городам
Двенадцать строк — четыре города по три отчёта. Сеть живёт в четырёх городах: Казань, Москва, Сочи и Омск, и строки таблицы идут в том порядке, в котором отчёты упали в общую папку.
import pandas as pd
sales = pd.DataFrame({
"city": ["Казань", "Казань", "Казань", "Москва", "Москва", "Москва",
"Сочи", "Сочи", "Сочи", "Омск", "Омск", "Омск"],
"revenue": [210, 230, 220, 320, 340, 330, 180, 200, 190, 120, 130, 110],
})
print(sales)
city revenue 0 Казань 210 1 Казань 230 2 Казань 220 3 Москва 320 4 Москва 340 5 Москва 330 6 Сочи 180 7 Сочи 200 8 Сочи 190 9 Омск 120 10 Омск 130 11 Омск 110
Столбец city — категория, столбец revenue — число. barplot соединяет ровно такую пару: категория по X, число по Y.
barplot: среднее и доверительный интервал одной строкой
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sales = pd.DataFrame({
"city": ["Казань", "Казань", "Казань", "Москва", "Москва", "Москва",
"Сочи", "Сочи", "Сочи", "Омск", "Омск", "Омск"],
"revenue": [210, 230, 220, 320, 340, 330, 180, 200, 190, 120, 130, 110],
})
sns.set_theme()
ax = sns.barplot(data=sales, x="city", y="revenue")
ax.set_title("Средняя выручка магазина по городам, тыс. руб.")
ax.set_ylabel("Тыс. руб.")
plt.show()
График отображается под редактором
Одна строка sns.barplot сделала всё, что в Matplotlib занимало две операции и импорт pandas: сгруппировала отчёты по city, посчитала средний revenue в каждой группе и нарисовала четыре столбца. Сверим с ручным подсчётом — посчитаем средние сами:
import pandas as pd
sales = pd.DataFrame({
"city": ["Казань", "Казань", "Казань", "Москва", "Москва", "Москва",
"Сочи", "Сочи", "Сочи", "Омск", "Омск", "Омск"],
"revenue": [210, 230, 220, 320, 340, 330, 180, 200, 190, 120, 130, 110],
})
print(sales.groupby("city")["revenue"].mean())
city Казань 220.0 Москва 330.0 Омск 120.0 Сочи 190.0 Name: revenue, dtype: float64
Цифры совпали со столбцами: Москва 330, Казань 220, Сочи 190, Омск 120. Разница barplot и plt.bar ровно в этой автоматической агрегации: plt.bar рисует то, что вы ему дали, barplot сначала считает. groupby, которым мы проверяли, разобран в уроке про группировку Pandas.
Что рассказывают усики
Над каждым столбцом — чёрная линия-усик. Высота столбца barplot — это среднее по группе, а усики показывают, насколько этому среднему можно верить. По умолчанию это 95-процентный доверительный интервал, оценённый бутстрепом. Интуитивно: усик — зона, где с большой вероятностью лежит настоящее среднее, если бы мы собрали не три отчёта, а все отчёты мира. У нас значения внутри города близкие, поэтому усики узкие. Уберите из Москвы два отчёта и оставьте один аномально высокий — среднее останется высоким, но усик распахнётся: данных мало, уверенности нет. Широкий усик на графике — всегда сигнал: в этой группе мало наблюдений или большой разброс.
order: порядок столбцов задаёте вы
Посмотрите на первый barplot ещё раз: столбцы идут Казань, Москва, Сочи, Омск — в порядке появления строк в таблице. Взгляд читает высоты слева направо, и прыжки 220 → 330 → 190 → 120 мешают сравнить города. Для отчёта столбцы сортируют по значению:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sales = pd.DataFrame({
"city": ["Казань", "Казань", "Казань", "Москва", "Москва", "Москва",
"Сочи", "Сочи", "Сочи", "Омск", "Омск", "Омск"],
"revenue": [210, 230, 220, 320, 340, 330, 180, 200, 190, 120, 130, 110],
})
sns.set_theme()
order = sales.groupby("city")["revenue"].mean().sort_values(ascending=False).index
ax = sns.barplot(data=sales, x="city", y="revenue", order=order)
ax.set_title("Города по убыванию средней выручки")
ax.set_ylabel("Тыс. руб.")
plt.show()
График отображается под редактором
Параметр order= принимает список категорий: order=["Москва", "Казань", "Сочи", "Омск"] тоже сработал бы. Здесь мы собрали список автоматически — средние по городам, отсортированные по убыванию. Порядок, который не зависит от порядка строк в таблице, — это ещё и воспроизводимость: отчёт перегенерировался, столбцы остались на местах. На следующем уроке этот же параметр наведёт календарный порядок в днях недели.
Что дальше
Вы научились сравнивать категории по среднему: barplot сам считает, сам рисует усики и доверяет порядок столбцов параметру order. Следующий урок — countplot: когда числового столбца нет вовсе и нужно просто посчитать строки.
Столбец barplot — среднее по группе, усики — её надёжность: широкий усик говорит о малых данных громче любого примечания под графиком.
Сначала предскажи ответ в голове — это главный навык программиста.
import pandas as pd
sales = pd.DataFrame({
"city": ["Казань", "Москва", "Казань", "Омск"],
"revenue": [210, 320, 230, 120],
})
print(sales.groupby("city")["revenue"].mean().loc["Казань"])
import pandas as pd
import seaborn as sns
sales = pd.DataFrame({
"city": ["Казань", "Москва", "Сочи", "Омск"],
"revenue": [220, 330, 190, 120],
})
ax = sns.barplot(data=sales, x="city", y="revenue", errorbar=None)
print(len(ax.patches))
1. Что по умолчанию показывает высота столбца sns.barplot?
2. Что означают чёрные усики над столбцами barplot?
3. В таблице Казань встречается раньше Москвы, но на графике Москва должна быть первой. Что сделать?
4. Чем seaborn barplot отличается от countplot?
5. На графике у одного города усик в три раза шире, чем у остальных. О чём это говорит?
По таблице отчётов трёх городов постройте barplot средней выручки: столбцы должны идти в порядке Москва, Казань, Омск. Тему и заголовок оставьте на ваше усмотрение — главное, порядок столбцов задан параметром order.
Что означают усики над столбцами в seaborn barplot?
Это 95-процентный доверительный интервал среднего, оценённый бутстрепом: зона, где с большой вероятностью лежит настоящее среднее группы. Широкий усик — мало наблюдений или большой разброс. Убрать усики можно параметром errorbar=None, а суммарные значения barplot не показывает — он усредняет.
Урок 3: countplot — сколько чегоКак отсортировать столбцы barplot по убыванию?
Передайте список категорий в order: sns.barplot(data=df, x="city", y="revenue", order=["Москва", "Казань", "Сочи"]). Автоматически список собирается из groupby: order=df.groupby("city")["revenue"].mean().sort_values(ascending=False).index.
Почему seaborn barplot показывает не сумму, а среднее?
Так задуман график: barplot отвечает на вопрос «сколько в среднем приносит категория» и добавляет к ответу доверительный интервал. Если нужна сумма — считайте её явно через df.groupby("city")["revenue"].sum() и рисуйте plt.bar, либо передайте estimator="sum" в Seaborn 0.13+. Усики при сумме теряют смысл и отключаются errorbar=None.
Чем barplot отличается от plt.bar из Matplotlib?
plt.bar рисует ровно те высоты, которые вы передали, — агрегацию делает pandas до него. barplot принимает сырые строки таблицы и сам группирует, усредняет и оценивает надёжность. Для сырых данных barplot короче, для заранее посчитанных итогов plt.bar честнее и быстрее.
Понравился урок? Сошлитесь на него
«Высота столбца barplot — это среднее по группе, а усики показывают, насколько этому среднему можно верить.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что читать дальше
Seaborn · Урок 1
Что такое Seaborn: первый график одной строкой
Seaborn — надстройка над Matplotlib: график из пары строк, тема и подписи осей из DataFrame прилагаются. Рисуем первый lineplot и сравниваем с ручным pyplot.
Seaborn · Урок 3
countplot в Seaborn: сколько чего встречается в данных
countplot рисует частоты категорий из сырых строк таблицы: без value_counts и без ручного plt.bar. Лог заказов, календарный порядок дней и горизонтальный вариант — за один урок.
Pandas · Урок 5
Группировка groupby в Pandas: агрегация как в Excel, только мощнее
groupby, agg и pivot_table — считаем выручку по городам и товарам, строим сводные таблицы и не теряем строки с NaN.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Matplotlib / Seaborn · Урок 10
Проект по визуализации: дашборд данных о фильмах на Matplotlib и Seaborn
Финальный проект курса: датасет из 200 фильмов, EDA, дашборд 2x2 с трендом, жанрами, гистограммой и scatter — плюс чек-лист «график готов к показу» и итоги десяти уроков.
matplotlib seabornстолбчатая диаграмма python
Matplotlib / Seaborn · Урок 3
Столбчатые диаграммы и гистограммы в Matplotlib: bar и hist
bar и barh для сравнения категорий, hist для распределений, параметр bins, план против факта и подписи значений над столбцами.
столбчатая диаграмма pythonгоризонтальная диаграмма barh
Seaborn · Урок 16
regplot: тренд и регрессия на графике рассеяния
Точки, линия регрессии и доверительная полоса одним вызовом regplot: как увидеть тренд двух величин, когда прямая врёт и что говорит наклон.
seaborn regplotлиния тренда seaborn