Палитры цветов в Seaborn: как подобрать цвета под задачу
Три типа палитр Seaborn, функция sns.color_palette(), безопасный набор colorblind и своя палитра из фирменных цветов — одна строка palette= на каждый случай.
Редакция Питоники
Цвет — самый громкий канал на графике: глаз цепляется за него раньше, чем за подписи и числа. В седьмом уроке про темы мы настроили фон, сетку и шрифты; остался последний слой оформления — палитра. Seaborn собрал десятки готовых наборов цветов и простые правила их выбора: одна строка palette= отделяет аккуратный отчёт от пёстрого наброска.
В этом уроке разберёмся, какие бывают палитры, как посмотреть их цвета через sns.color_palette(), какой набор выбрать для категорий, а какой — для величин с порядком, и почему параметр palette="colorblind" стоит запомнить с первого дня работы с библиотекой.
Три типа палитр: категории, порядок, отклонение
Вся система палитр Seaborn держится на одном вопросе: что означает цвет на вашем графике? Ответов три, и под каждый построен свой тип наборов.
| Тип палитры | Что кодирует цвет | Примеры |
|---|---|---|
| Категориальная (qualitative) | «Какой это тип»: жанры, города, каналы | deep, Set2, colorblind |
| Последовательная (sequential) | «Сколько»: от малого к большому | Blues, YlGnBu, viridis |
| Дивергентная (diverging) | «В какую сторону от середины»: прибыль и убыток | RdBu_r, coolwarm, PiYG |
Категории отвечают на вопрос «какой», последовательные — «сколько», дивергентные — «в какую сторону от середины». Перепутать их — значит вложить в цвет смысл, которого в данных нет: последовательная палитра на списке жанров намекнёт читателю, что «фантастика больше романа», хотя сравнивать жанры на шкале нельзя.
sns.color_palette(): посмотреть цвета до графика
Функция sns.color_palette() возвращает палитру как список кортежей RGB — три числа от 0 до 1 на каждый цвет. Это самый быстрый способ осмотреть набор: сколько в нём цветов и какие они.
import seaborn as sns
palette = sns.color_palette("Set2")
print(len(palette))
print([round(c, 2) for c in palette[0]])
8 [0.4, 0.76, 0.65]
Восемь цветов, и первый — приглушённый зелёный с координатами (0.4, 0.76, 0.65). Числа — доли красного, зелёного и синего канала: (1, 0, 0) — чистый красный, (0, 0, 0) — чёрный. Те же кортежи подходят любому методу Matplotlib в параметре color= — палитры Seaborn и цвета Matplotlib говорят на одном языке.
Категориальные палитры: цвета как ярлыки
Категориальные наборы собраны из заметно различающихся оттенков: deep (палитра по умолчанию), muted, pastel, bright, dark, colorblind и тематические наборы ColorBrewer вроде Set2. Применяются параметром palette= в любой функции построения графика:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
books = pd.DataFrame({
"genre": ["роман", "детектив", "фантастика", "детская",
"нонфикшн", "роман", "детектив", "фантастика"],
"sales": [42, 35, 28, 51, 19, 38, 31, 24],
})
sns.set_theme()
ax = sns.barplot(
data=books, x="genre", y="sales",
hue="genre", palette="Set2", legend=False,
)
ax.set_title("Продажи по жанрам: палитра Set2")
plt.show()
График отображается под редактором
Пара hue="genre", legend=False — типовой приём Seaborn 0.13: цвет по категории, но без дублирующей легенды, потому что имена жанров уже стоят по оси X. С версии 0.13 параметр palette= без hue= считается устаревшим — об этом отдельный питфолл ниже.
colorblind: палитра, которую видят все
Около 8% мужчин имеют нарушение цветовосприятия, и классическая пара красный-зелёный для них сливается в одно пятно. Палитра colorblind построена на наборе Okabe-Ito, который специально подобран различимым при дальтонизме, — тот же принцип мы упоминали в уроке про оформление Matplotlib. Сравните наборы рядом:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
books = pd.DataFrame({
"genre": ["роман", "детектив", "фантастика", "детская",
"нонфикшн", "роман", "детектив", "фантастика"],
"sales": [42, 35, 28, 51, 19, 38, 31, 24],
})
sns.set_theme()
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(11, 4), sharey=True)
sns.barplot(data=books, x="genre", y="sales", hue="genre",
legend=False, ax=ax1)
sns.barplot(data=books, x="genre", y="sales", hue="genre",
palette="colorblind", legend=False, ax=ax2)
ax1.set_title("Палитра по умолчанию (deep)")
ax2.set_title("Палитра colorblind")
plt.show()
График отображается под редактором
Сравните второй цвет в каждой панели: в deep это красновато-оранжевый, в colorblind — отчётливо оранжевый, а красно-зелёных пар в наборе нет вовсе. Для отчёта, который уйдёт заказчику или в печать (где цвета искажаются ещё и на бумаге), colorblind — безопасный выбор по умолчанию. Включить его глобально можно вызовом sns.set_palette("colorblind"):
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
orders = pd.DataFrame({
"genre": ["роман", "детектив", "фантастика", "детская",
"нонфикшн", "роман", "детектив", "фантастика"],
})
sns.set_theme()
sns.set_palette("colorblind") # все графики ниже рисуются в colorblind
ax = sns.countplot(data=orders, x="genre", hue="genre", legend=False)
ax.set_title("Палитра включена глобально")
plt.show()
График отображается под редактором
set_palette работает как set_theme из седьмого урока: меняет настройку сессии, и все последующие графики рисуются уже в ней. Удобно включить один раз в начале ноутбука и не думать о палитре дальше — параметр palette= останется для точечных исключений.
Последовательные палитры: когда величина имеет порядок
Если цвет кодирует количество — выручку, плотность, время — нужен набор, где оттенок плавно меняется от светлого к тёмному: Blues, Greens, YlGnBu, viridis. Посмотрим на крайние ступени градиента числом:
import seaborn as sns
blues = sns.color_palette("Blues", n_colors=5)
print([round(c, 2) for c in blues[0]])
print([round(c, 2) for c in blues[-1]])
[0.84, 0.9, 0.96] [0.06, 0.36, 0.64]
Первый цвет почти белый, последний — насыщенный синий: аргумент n_colors= задаёт число ступеней градиента. Тёмный оттенок считывается как «больше» мгновенно — на этом держатся тепловые карты, до которых доберёмся в уроке про heatmap. А пока применим градиент к столбцам вручную:
import matplotlib.pyplot as plt
import seaborn as sns
days = ["Пн", "Вт", "Ср", "Чт", "Пт"]
visits = [120, 95, 88, 140, 205]
grad = sns.color_palette("Blues", n_colors=5)
sns.set_theme()
fig, ax = plt.subplots()
ax.bar(days, visits, color=grad)
ax.set_title("Посещения по дням: чем темнее, тем больше")
ax.set_ylabel("Посещения")
plt.show()
График отображается под редактором
Здесь градиент честный: он упорядочен вместе со значениями visits — от спокойного понедельника к горячей пятнице. Порядок цветов совпал с порядком величин, и цвет работает на график, а не против него.
Дивергентные палитры: вокруг середины
Когда значения отклоняются от нормы — прибыль и убыток, отклонение температуры от среднего — нужна дивергентная палитра: два насыщенных края и бледная середина. Названия говорят сами за себя: RdBu_r (красный-синий), coolwarm, PiYG. Полная сила этих наборов раскроется в тепловых картах, а здесь — та же логика на столбцах прибыли:
import matplotlib.pyplot as plt
import seaborn as sns
months = ["Март", "Апрель", "Май", "Июнь", "Июль"]
profit = [-12, 5, 18, -4, 25]
colors = ["#b2182b" if p < 0 else "#2166ac" for p in profit]
sns.set_theme()
fig, ax = plt.subplots()
ax.bar(months, profit, color=colors)
ax.axhline(0, color="black", linewidth=0.8)
ax.set_title("Прибыль по месяцам: дивергентная логика")
ax.set_ylabel("Тыс. руб.")
plt.show()
График отображается под редактором
Нулевая линия делит график на две зоны, и цвет усиливает разделение: убытки красным, прибыль синим. Читатель понимает знак каждого столбца раньше, чем успевает посмотреть на ось Y, — именно эту скорость и покупают за дивергентную палитру.
Своя палитра: фирменные цвета
Палитрой может стать любой список цветов — hex-строками или RGB-кортежами. Фирменные цвета компании или единая гамма для дашборда — это один вызов:
import seaborn as sns
brand = sns.color_palette(["#2a9d8f", "#e9c46a", "#e76f51"])
print(len(brand))
print([round(c, 2) for c in brand[0]])
3 [0.16, 0.62, 0.56]
Три цвета бренда готовы к работе: список можно передать прямо в palette= или обернуть в sns.color_palette(), чтобы получить RGB-кортежи для Matplotlib. Если нужно равномерно разложить оттенки по цветовому кругу, пригодится sns.husl_palette(8) — она вернёт восемь максимально различимых цветов, а аргументом задаётся нужное количество.
Что дальше
Арсенал собран: три типа палитр, color_palette() для осмотра, colorblind для безопасности, глобальная set_palette и свои списки цветов. Осталось главное применение цвета — кодировать третье измерение данных: следующий урок разбирает параметр hue, который раскрашивает точки и столбцы по значениям ещё одной колонки. А финальный проект курса соберёт палитры и всё остальное в дашборд аналитики магазина.
Категории отвечают на вопрос «какой», последовательные — «сколько», дивергентные — «в какую сторону от середины».
Сначала предскажи ответ в голове — это главный навык программиста.
import seaborn as sns
pal = sns.color_palette("Set2")
print(len(pal))
import seaborn as sns
custom = sns.color_palette(["#e41a1c", "#377eb8", "#4daf4a"])
print(len(custom))
import seaborn as sns
pal = sns.color_palette("colorblind")
print(len(pal))
1. Что возвращает функция sns.color_palette("Set2")?
2. Цвет должен кодировать плотность населения районов. Какой тип палитры выбрать?
3. Чем палитра colorblind лучше палитры deep для отчёта заказчику?
4. Что произойдёт при вызове sns.countplot(data=df, x="day", palette="Set2") в Seaborn 0.13?
5. Данные: прибыль по месяцам с плюсом и минусом. Какая палитра передаст это лучше всего?
В редакторе — продажи книжного магазина по жанрам. Постройте barplot среднего объёма продаж по жанрам с палитрой colorblind: разбивка hue="genre" без легенды и заголовок «Продажи по жанрам».
Как задать свои цвета в Seaborn?
Передайте список цветов прямо в параметр palette=: palette=["#2a9d8f", "#e9c46a", "#e76f51"]. Если нужны RGB-кортежи для Matplotlib, оберните список в sns.color_palette() — она вернёт те же цвета числами от 0 до 1. Для равномерного набора оттенков есть sns.husl_palette(8).
Урок 8: палитры цветовКакая палитра Seaborn безопасна для дальтоников?
palette="colorblind" — она построена на наборе Okabe-Ito, подобранном различимым при нарушениях цветовосприятия, и не содержит красно-зелёных пар. Включить её для всех графиков сессии можно вызовом sns.set_palette("colorblind").
Чем последовательная палитра отличается от дивергентной?
Последовательная (Blues, viridis) — градиент от светлого к тёмному для величин с порядком: чем темнее, тем больше. Дивергентная (RdBu_r, coolwarm) — два насыщенных края и бледная середина для отклонений от нормы: прибыль и убыток, корреляции от -1 до 1.
Почему palette без hue выдаёт FutureWarning?
В Seaborn 0.13 параметр palette= без hue= считается устаревшим: поведение неочевидно, поэтому библиотека предупреждает FutureWarning, а в 0.14 вызов перестанет работать. Добавьте hue= с колонкой категорий и legend=False, если легенда дублирует подписи оси.
Понравился урок? Сошлитесь на него
«Категории отвечают на вопрос «какой», последовательные — «сколько», дивергентные — «в какую сторону от середины».»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что читать дальше
Seaborn · Урок 7
Темы Seaborn: set_theme, стили и контекст графика
Пять тем Seaborn на один вызов: whitegrid для отчётов, darkgrid для экрана, ticks для строгих публикаций. Контекст talk укрупняет шрифты, despine снимает лишние линии рамки.
Seaborn · Урок 9
hue в Seaborn: цвет как третье измерение графика
hue разбивает график по третьей колонке таблицы: точки, столбцы и линии раскрашиваются по группам, а легенда строится сама. Разбираем scatterplot, barplot, lineplot и hue_order.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Matplotlib / Seaborn · Урок 1
Визуализация данных в Python: первое знакомство с Matplotlib
Первый график в Python за три строки кода, анатомия figure и axes, шпаргалка «какой график для каких данных» и сохранение в PNG. Всё запускается прямо на странице.
построение графиков pythonкак сделать график в matplotlib пошагово
Matplotlib / Seaborn · Урок 2
Линейные графики в Matplotlib: plot, цвета, стили и подписи
plt.plot() под микроскопом: цвета, маркеры, стили линий, легенды, диапазоны осей и кейс с двумя температурными кривыми за месяц.
линейный график pythonкак построить линейный график в python
Seaborn · Урок 14
jointplot в Seaborn: связь двух величин и распределения по краям
jointplot рисует связь двух величин в центре и их распределения по краям: сгущения и выбросы видны одновременно. kind="kde" и kind="hex" для плотных данных.
seaborn jointplotгистограмма по краям графика