Перейти к содержанию

252 уроков, 17 библиотек и челлендж «Что выведет код?» — бесплатно, код прямо в браузере

Начать обучение
Урок 2 из 20 Средний 30 мин 120 XP

barplot в Seaborn: средние по категориям с интервалами

sns.barplot усредняет числовой столбец по категориям и добавляет усики доверительного интервала. Сравниваем выручку магазинов в четырёх городах и наводим порядок через order.

Редакция Питоники

У сети из четырёх магазинов — по три месячных отчёта на город. Вопрос директора простой: где выручка выше и можно ли ей верить? В Matplotlib ответ собирался в два хода: сначала groupby().mean() в pandas, потом plt.bar по результату. Seaborn делает это одной строкой — и заодно честно показывает, насколько каждому среднему можно верить.

Урок разбирает sns.barplot по косточкам: что такое усики над столбцами, почему высота — это среднее, а не сумма, и как параметр order наводит порядок в столбцах.

Данные: выручка по городам

Двенадцать строк — четыре города по три отчёта. Сеть живёт в четырёх городах: Казань, Москва, Сочи и Омск, и строки таблицы идут в том порядке, в котором отчёты упали в общую папку.

Отчёты сети: 12 строк
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 мешают сравнить города. Для отчёта столбцы сортируют по значению:

Столбцы по убыванию: order
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))
Проверь себя
0 / 5

1. Что по умолчанию показывает высота столбца sns.barplot?

2. Что означают чёрные усики над столбцами barplot?

3. В таблице Казань встречается раньше Москвы, но на графике Москва должна быть первой. Что сделать?

4. Чем seaborn barplot отличается от countplot?

5. На графике у одного города усик в три раза шире, чем у остальных. О чём это говорит?

Карточки терминов
Запомнено: 0 / 6
Практика

По таблице отчётов трёх городов постройте barplot средней выручки: столбцы должны идти в порядке Москва, Казань, Омск. Тему и заголовок оставьте на ваше усмотрение — главное, порядок столбцов задан параметром order.

practice.py
Вопросы и ответы по уроку

Что означают усики над столбцами в 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-канал или свой блог — так о проекте узнают новые читатели.

TelegramVK

Похожие уроки по темам

Подобраны автоматически по пересечению тем и ключевых слов.