Кладовочка

О разном, чтобы было под рукой онлайн

Шпаргалка по Seaborn: статистическая визуализация

Seaborn — надстройка над Matplotlib для статистической визуализации. Автоматические стили, доверительные интервалы, умные подписи, встроенные датасеты. Идеален для исследовательского анализа данных (EDA).

Быстрый старт

Первые шаги: импорт seaborn, загрузка встроенных датасетов (tips, penguins, iris), настройка темы. Эти датасеты идеальны для обучения — не нужно искать данные, чтобы попробовать графики.

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# Встроенные датасеты
tips = sns.load_dataset('tips')
penguins = sns.load_dataset('penguins')
iris = sns.load_dataset('iris')
titanic = sns.load_dataset('titanic')
flights = sns.load_dataset('flights')

# Настройка темы
sns.set_theme(style='darkgrid', palette='muted', font='DejaVu Sans')

Распределения

Ответ на вопрос «как распределены данные?»: гистограммы (histplot), ядерная оценка плотности (kdeplot — гладкая кривая вместо столбцов), эмпирическая CDF (ecdfplot). displot — figure-level версия, которая сама управляет сеткой подграфиков.

# Гистограмма
sns.histplot(data=tips, x='total_bill', bins=30)
sns.histplot(data=tips, x='total_bill', hue='sex', multiple='stack')  # с разбивкой
sns.histplot(data=tips, x='total_bill', kde=True)                      # + KDE

# KDE (ядерная оценка плотности)
sns.kdeplot(data=tips, x='total_bill', fill=True)
sns.kdeplot(data=tips, x='total_bill', hue='smoker', fill=True, alpha=0.3)

# ECDF (эмпирическая CDF)
sns.ecdfplot(data=tips, x='total_bill', hue='time')

# Универсальный displot (figure-level)
sns.displot(data=tips, x='total_bill', kde=True)        # гистограмма + KDE
sns.displot(data=tips, x='total_bill', hue='sex')       # по группам
sns.displot(data=tips, x='total_bill', col='day')       # по дням сеткой
sns.displot(data=tips, x='total_bill', kind='kde')
sns.displot(data=tips, x='total_bill', kind='ecdf')

Категориальные данные

Сравнение числовой переменной по категориям: boxplot (медиана + квартили), violin (плотность + boxplot), boxen (больше квантилей для больших данных), stripplot/swarmplot (точки), barplot (среднее ± доверительный интервал), countplot (частоты). catplot — figure-level универсал.

# Boxplot
sns.boxplot(data=tips, x='day', y='total_bill')                       # базовый
sns.boxplot(data=tips, x='day', y='total_bill', hue='smoker')         # с подгруппами
sns.boxplot(data=tips, y='total_bill', hue='day')                     # горизонтальная группировка

# Violin plot (плотность + boxplot)
sns.violinplot(data=tips, x='day', y='total_bill')
sns.violinplot(data=tips, x='day', y='total_bill', hue='sex', split=True)  # пол внутри категории
sns.violinplot(data=tips, x='day', y='total_bill', inner='quartile')       # квартили внутри

# Boxen plot (для больших данных — больше квантилей)
sns.boxenplot(data=tips, x='day', y='total_bill')

# Stripplot / Swarmplot (точки)
sns.stripplot(data=tips, x='day', y='total_bill', jitter=True, alpha=0.5)
sns.swarmplot(data=tips, x='day', y='total_bill', size=4)  # без наложения

# Комбинация: boxplot + точки
sns.boxplot(data=tips, x='day', y='total_bill')
sns.swarmplot(data=tips, x='day', y='total_bill', color='black', size=3, alpha=0.5)

# Countplot
sns.countplot(data=titanic, x='class')                             # частоты
sns.countplot(data=titanic, x='class', hue='survived')             # с подгруппами

# Barplot (среднее + CI)
sns.barplot(data=tips, x='day', y='total_bill')                    # среднее
sns.barplot(data=tips, x='day', y='total_bill', hue='sex')         # по полу

# Pointplot (точки + линия для трендов)
sns.pointplot(data=tips, x='day', y='total_bill', hue='sex')

# Универсальный catplot (figure-level)
sns.catplot(data=tips, x='day', y='total_bill', kind='box')
sns.catplot(data=tips, x='day', y='total_bill', kind='violin', col='sex')
sns.catplot(data=tips, x='day', kind='count', hue='time')
sns.catplot(data=tips, x='day', y='total_bill', kind='bar', col='time')

Реляционные графики

Связь между двумя числовыми переменными: scatterplot (точки), lineplot (линия с доверительным интервалом — идеален для временных рядов), lmplot (линейная регрессия). relplot — figure-level с автоматической сеткой по hue/col/row.

# Scatterplot
sns.scatterplot(data=tips, x='total_bill', y='tip')
sns.scatterplot(data=tips, x='total_bill', y='tip', hue='sex')       # цвет=пол
sns.scatterplot(data=tips, x='total_bill', y='tip',
                hue='time', size='size', sizes=(20, 200))            # цвет+размер

# Lineplot (с доверительным интервалом)
sns.lineplot(data=tips, x='total_bill', y='tip')                     # CI по умолчанию
sns.lineplot(data=tips, x='total_bill', y='tip', hue='sex')         # по группам
sns.lineplot(data=tips, x='total_bill', y='tip',
             ci='sd', err_style='band')                               # std вместо 95% CI
sns.lineplot(data=tips, x='total_bill', y='tip', ci=None)           # без CI

# lmplot (регрессия)
sns.lmplot(data=tips, x='total_bill', y='tip')                       # линейная регрессия
sns.lmplot(data=tips, x='total_bill', y='tip', hue='smoker')        # по группам
sns.lmplot(data=tips, x='total_bill', y='tip', col='day')           # сеткой по дням

# Универсальный relplot (figure-level)
sns.relplot(data=tips, x='total_bill', y='tip', kind='scatter')
sns.relplot(data=tips, x='total_bill', y='tip', kind='line', hue='sex')
sns.relplot(data=penguins, x='bill_length_mm', y='bill_depth_mm',
            hue='species', size='body_mass_g', sizes=(20, 200))

Heatmap и матрицы

Визуализация матриц и таблиц: heatmap — цветовая карта (корреляции, конфузионные матрицы, сводные таблицы). clustermap — heatmap + дендрограмма (иерархическая кластеризация строк и столбцов). Оба используют цвет для передачи значений.

# Корреляционная матрица
corr = df.corr(numeric_only=True)
sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm',
            center=0, square=True, linewidths=0.5,
            cbar_kws={'shrink': 0.8})

# Кастомные параметры
sns.heatmap(corr, annot=True, fmt='.2f', cmap='RdBu_r',
            vmin=-1, vmax=1, center=0,         # фиксированный диапазон
            square=True, linewidths=1,
            xticklabels=True, yticklabels=True,
            mask=np.triu(corr))                 # скрыть верхний треугольник

# Pivot → heatmap
pivot = flights.pivot(index='month', columns='year', values='passengers')
sns.heatmap(pivot, annot=True, fmt='d', cmap='YlOrRd')

# Кластерная карта (clustermap)
sns.clustermap(corr, annot=True, fmt='.2f', cmap='coolwarm',
               method='ward', figsize=(10, 8))

FacetGrid — сетки графиков

Создаёт сетку подграфиков, разделяя данные по значениям категориальных переменных (col, row, hue). Каждый подграфик — одинаковый тип (scatter, hist), но на своём подмножестве данных. col_wrap ограничивает число столбцов и переносит на новую строку.

# Figure-level API: функция возвращает FacetGrid
# (НЕ matplotlib axes, а объект FacetGrid!)

# Базовая сетка
g = sns.FacetGrid(tips, col='day', height=4, aspect=1)
g.map(sns.scatterplot, 'total_bill', 'tip')

# С hue
g = sns.FacetGrid(tips, col='day', hue='sex', height=4)
g.map(sns.scatterplot, 'total_bill', 'tip')
g.add_legend()

# Строки + столбцы
g = sns.FacetGrid(tips, col='time', row='sex', height=4)
g.map(sns.histplot, 'total_bill')

# col_wrap — перенос на новую строку
g = sns.FacetGrid(tips, col='day', col_wrap=2, height=3)
g.map(sns.scatterplot, 'total_bill', 'tip')

# Кастомная функция с map_dataframe
def scatter_with_stats(data, **kwargs):
    ax = plt.gca()
    sns.scatterplot(data=data, **kwargs)
    ax.axvline(data['total_bill'].mean(), color='red', linestyle='--')
    ax.axhline(data['tip'].mean(), color='red', linestyle='--')
    ax.text(0.95, 0.95, f'n={len(data)}', transform=ax.transAxes,
            ha='right', va='top', fontsize=12)

g = sns.FacetGrid(tips, col='day', height=4)
g.map_dataframe(scatter_with_stats, x='total_bill', y='tip')
g.set_axis_labels('Счёт ($)', 'Чаевые ($)')
g.set_titles('День: {col_name}')

PairGrid и pairplot

Матрица попарных отношений между всеми числовыми переменными. pairplot — быстрый обзор всего датасета. PairGrid — полный контроль: можно задать разные типы графиков для диагонали, верхнего и нижнего треугольника. Идеально для первого взгляда на данные.

# pairplot — быстрый обзор всех попарных отношений
sns.pairplot(penguins, hue='species')
sns.pairplot(penguins, hue='species', diag_kind='kde')     # KDE на диагонали
sns.pairplot(penguins, hue='species', corner=True)          # только нижний треугольник
sns.pairplot(penguins, hue='species', markers=['o', 's', 'D'])
sns.pairplot(penguins, vars=['bill_length_mm', 'bill_depth_mm', 'body_mass_g'])  # выборочно

# PairGrid — полный контроль
g = sns.PairGrid(penguins, hue='species')

g.map_upper(sns.scatterplot, s=10)               # scatter сверху
g.map_lower(sns.kdeplot, fill=True, alpha=0.3)   # KDE снизу
g.map_diag(sns.histplot, kde=True, alpha=0.5)    # гистограмма на диагонали
g.add_legend()

# С функцией корреляции
def corr_func(x, y, **kwargs):
    r = np.corrcoef(x, y)[0, 1]
    ax = plt.gca()
    ax.annotate(f'r = {r:.2f}', xy=(0.5, 0.9), xycoords='axes fraction',
                ha='center', fontsize=12)

g = sns.PairGrid(penguins, hue='species')
g.map_upper(sns.scatterplot)
g.map_lower(sns.kdeplot)
g.map_diag(sns.histplot)
g.map_upper(corr_func)  # r на верхней панели
g.add_legend()

JointGrid и jointplot

Связь двух переменных + их маргинальные распределения на одном графике. Основное поле — scatter/hexbin/kde/regression, боковые поля — гистограммы/KDE. jointplot — быстро, JointGrid — полный контроль над каждым элементом.

# jointplot — связь двух переменных + маргинальные распределения
sns.jointplot(data=tips, x='total_bill', y='tip')                    # scatter
sns.jointplot(data=tips, x='total_bill', y='tip', kind='hex')       # hexbin
sns.jointplot(data=tips, x='total_bill', y='tip', kind='kde')       # KDE
sns.jointplot(data=tips, x='total_bill', y='tip', kind='reg')       # + регрессия

# JointGrid — полный контроль
g = sns.JointGrid(data=tips, x='total_bill', y='tip')
g.plot_joint(sns.scatterplot)              # центральный график
g.plot_marginals(sns.histplot, kde=True)   # маргинальные

# С корреляцией
g = sns.JointGrid(data=tips, x='total_bill', y='tip')
g.plot_joint(sns.scatterplot)
g.plot_marginals(sns.histplot)
r = tips['total_bill'].corr(tips['tip'])
g.ax_joint.text(0.05, 0.95, f'r = {r:.2f}', transform=g.ax_joint.transAxes,
                fontsize=12, va='top')

Цветовые палитры

Цвет — мощный канал передачи информации. Qualitative палитры (deep, muted) — для категорий. Sequential (rocket, mako) — для чисел. Diverging (coolwarm, RdBu) — для отклонений. Можно создавать свои через sns.color_palette() и sns.light_palette().

# Типы палитр
# Qualitative (категории): 'deep', 'muted', 'pastel', 'bright', 'dark', 'colorblind'
# Sequential (числа): 'rocket', 'mako', 'flare', 'crest', 'viridis'
# Diverging (отклонения): 'coolwarm', 'RdBu', 'icefire', 'vlag'

# Просмотр палитры
sns.palplot(sns.color_palette('muted', 10))

# Установка палитры
sns.set_palette('muted')
sns.set_palette('husl', 8)              # HUSL цветовое пространство

# Кастомные палитры
palette = sns.color_palette(['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'])
palette = sns.light_palette('navy', n_colors=5)          # светлая → тёмная
palette = sns.dark_palette('gold', n_colors=5)
palette = sns.diverging_palette(250, 15, n=7)            # синий → красный

# Кастомная цветовая карта (colormap)
from matplotlib.colors import LinearSegmentedColormap
colors = ['blue', 'white', 'red']
cmap = LinearSegmentedColormap.from_list('custom', colors, N=256)

sns.heatmap(corr, cmap=cmap, center=0)

# Использование в графиках
sns.scatterplot(data=tips, x='total_bill', y='tip', hue='day', palette='Set2')

Контексты и стили

Готовые наборы оформления для разных ситуаций: paper (мелкие подписи — для статей), notebook (по умолчанию), talk (средние — для презентаций), poster (крупные — для постеров). Стили (darkgrid, whitegrid, ticks) меняют фон и сетку.

# Стили осей (фон + сетка)
sns.set_style('darkgrid')      # тёмный фон с белой сеткой
sns.set_style('whitegrid')     # белый фон с серой сеткой
sns.set_style('dark')          # тёмный фон без сетки
sns.set_style('white')         # белый фон без сетки
sns.set_style('ticks')         # белый + деления

# Контексты (размер элементов)
sns.set_context('paper')       # для статей (мелкий)
sns.set_context('notebook')    # для ноутбуков (по умолчанию)
sns.set_context('talk')        # для презентаций (средний)
sns.set_context('poster')      # для постеров (крупный)

# Тонкая настройка
sns.set_context('talk', font_scale=1.2)  # + масштабирование шрифта

# Кастомный стиль
custom_style = {
    'axes.facecolor': '#f0f0f0',
    'axes.edgecolor': '#333333',
    'axes.grid': True,
    'axes.spines.top': False,
    'axes.spines.right': False,
    'grid.color': '#cccccc',
    'grid.linestyle': '--',
}
sns.set_style(custom_style)

# Кастомный контекст
custom_context = {
    'font.size': 14,
    'axes.titlesize': 18,
    'axes.labelsize': 14,
    'xtick.labelsize': 12,
    'ytick.labelsize': 12,
    'legend.fontsize': 12,
    'lines.linewidth': 2.5,
    'lines.markersize': 8,
}
sns.set_context(custom_context)

Сочетание Seaborn + Matplotlib

Seaborn построен на Matplotlib. Axes-level функции (sns.scatterplot) возвращают ax — можно донастроить через matplotlib. Figure-level функции (sns.relplot) возвращают FacetGrid — доступ к фигуре через .figure и к осям через .axes[i, j].

# Seaborn графики возвращают matplotlib axes/figures
# (кроме figure-level: relplot, displot, catplot, lmplot, pairplot, jointplot)

# Axes-level — можно донастроить через matplotlib
fig, ax = plt.subplots(figsize=(10, 6))
sns.scatterplot(data=tips, x='total_bill', y='tip', hue='day', ax=ax)
ax.set_title('Чаевые vs счёт', fontsize=14)
ax.axhline(y=tips['tip'].mean(), color='red', linestyle='--', label='Средние чаевые')
ax.legend()
fig.savefig('tips.png', dpi=150, bbox_inches='tight')

# Figure-level — доступ через .figure, .axes
g = sns.relplot(data=tips, x='total_bill', y='tip', col='day')

# Доступ к фигуре
g.figure.suptitle('Чаевые по дням', fontsize=16, y=1.02)
g.figure.savefig('tips_grid.png', dpi=150, bbox_inches='tight')

# Доступ к отдельным осям
g.axes[0, 0].set_title('Четверг (изменён)')
g.set_axis_labels('Счёт ($)', 'Чаевые ($)')

# Сложная компоновка: matplotlib GridSpec + seaborn
from matplotlib.gridspec import GridSpec

fig = plt.figure(figsize=(14, 10))
gs = GridSpec(3, 3, figure=fig)

# Главный scatter — вся верхняя строка
ax_main = fig.add_subplot(gs[0, :])
sns.scatterplot(data=tips, x='total_bill', y='tip', hue='sex', ax=ax_main)

# Гистограммы снизу
ax_hist_x = fig.add_subplot(gs[1, :2])
sns.histplot(data=tips, x='total_bill', ax=ax_hist_x)

ax_hist_y = fig.add_subplot(gs[1, 2])
sns.histplot(data=tips, y='tip', ax=ax_hist_y)

# Boxplot
ax_box = fig.add_subplot(gs[2, :])
sns.boxplot(data=tips, x='day', y='tip', hue='smoker', ax=ax_box)

plt.tight_layout()

Публикационный график (checklist)

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

sns.set_theme(style='whitegrid', font='DejaVu Sans')
sns.set_context('notebook', font_scale=1.1)

fig, ax = plt.subplots(figsize=(10, 6))

# 1. График
sns.scatterplot(
    data=penguins,
    x='bill_length_mm', y='bill_depth_mm',
    hue='species', size='body_mass_g',
    sizes=(30, 200), palette='Set2',
    alpha=0.8, edgecolor='black', linewidth=0.3,
    ax=ax
)

# 2. Подписи
ax.set_title('Пингвины: длина клюва vs глубина клюва',
             fontsize=14, fontweight='bold', pad=15)
ax.set_xlabel('Длина клюва (мм)', fontsize=12)
ax.set_ylabel('Глубина клюва (мм)', fontsize=12)

# 3. Легенда
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left',
          frameon=True, title='Вид', title_fontsize=11)

# 4. Сохранить
fig.savefig('penguins_publication.png', dpi=300, bbox_inches='tight')

Частые ошибки

Ошибка Правильно
Figure-level после axes-level (пустой график) Figure-level открывает свою фигуру — используй ДО axes-level
ax = sns.boxplot(...) — ax не всегда возвращается Figure-level (relplot, catplot, displot) возвращает FacetGrid, не ax!
Забыт data= для hue/col sns.scatterplot(x='a', y='b', hue='c') → нужно data=df
Слишком много hue (категорий > 10) Используй .nlargest(10) или объединяй категории
tight_layout с FacetGrid FacetGrid сам управляет layout — не нужен
Неправильный transform в figure-level Доступ к осям через g.axes[i, j]

Ресурсы

Что дальше


Связанные шпаргалки: Python, NumPy, Pandas, Matplotlib, SQL для начинающих