
Лучше один раз увидеть, чем сто раз услышать — в аналитике эта пословица работает на все сто. В новой статье разбираем, почему одна удачная визуализация объясняет процессы, зависимости и помогает найти инсайты быстрее, чем десятки слайдов с текстом и формулами. Также рассмотрим несколько оригинальных интерактивных визуализаций на Plotly — за пределами привычных распределений, боксплотов и прочих «школьных» графиков.
Об авторе: Мария Жарова — преподаватель Центра «Пуск» МФТИ, ML-инженер в Wildberries, автор канала EasyData.

Наглядные графики — не просто способ украсить презентацию. Они помогают быстрее доносить мысли, упрощают обсуждение, делают отчеты и статьи живее и заметно ускоряют анализ, позволяя быстрее обнаруживать интересные моменты и аномалии в данных. Визуализация — мощный инструмент как для дата-аналитика, так и для дата-сайентиста.
Особенно это становится заметно в ситуациях, где нужно объяснять сложные вещи на пальцах: поведение пользователей, взаимосвязи признаков, сравнение моделей или результаты A/B-тестов. Там, где таблицы и текст перегружают восприятие, хороший график, наоборот, снижает когнитивную нагрузку и помогает быстро уловить суть.
И конечно, интересные графики — еще и про вовлечение. Полезная картинка разнообразит слайд или отчет, а интерактивность привлечет внимание и усилит восприятие вашей работы.
Почему Plotly
Все примеры кода для графиков будем делать с помощью Plotly, и это неслучайный выбор. Plotly — это мощная python-библиотека для интерактивной визуализации данных, которая отлично подходит для презентаций, аналитических отчетов и дашбордов. В отличие от классических библиотек вроде Matplotlib, здесь доступна интерактивность: графики можно крутить, масштабировать, наводить курсор, смотреть точные значения и фильтровать буквально на лету.
Вторая сильная сторона Plotly — дизайн и гибкость кастомизации. Библиотека позволяет делать действительно вау-графики: сложные 3D-визуализации, анимированные переходы, sankey-диаграммы, sunburst-иерархии, интерактивные карты, network-графы и многое другое. При этом все это можно стилизовать под корпоративные цвета, презентации или дашборды.

Пример sankey-диаграммы, источник

Пример sunburst-иерархии, источник
Кстати, Plotly отлично интегрируется с Dash — фреймворком для создания полноценных аналитических веб-приложений на Python. Значит, график можно сначала показать в презентации, а потом встроить в production-дашборд для бизнеса или команды.
Графики Plotly легко встраиваются и в другие BI‑ и аналитические инструменты: их можно экспортировать в HTML (с полной интерактивностью) и интегрировать во внутренние порталы, Wiki, отчетные системы, а также использовать внутри кастомных интерфейсов. Через iframe или web‑вставки они без проблем соседствуют с Power BI, DataLens, Redash и другими дашборд‑решениями. Также это отличная находка для блогов, портфолио и обучающих материалов.
Официальную документацию библиотеки можно посмотреть по ссылке: https://plotly.com/python/ — там много готовых примеров, шаблонов и туториалов, от базовых графиков до продвинутых сценариев.
Здесь мы не будем разбирать принципы написания кода на Plotly и синтаксис библиотеки. К каждой визуализации я просто приведу готовый пример на Python, который можно адаптировать под свои данные. Если захотите углубиться, рекомендую покопаться в документации: помимо референса, там есть целая галерея крутых визуализаций, которые отлично прокачивают насмотренность и дают идеи для собственных оригинальных графиков.
Описание тестового датасета
Итак, приступим к построению. В качестве основы для экспериментов возьмем датасет с данными об уровне счастья по странам и присоединим к нему несколько столбцов с расширенной информацией о странах по данным, взятых также с Kaggle.

Семпл данных, с которым будем экспериментировать
Краткое описание итогового набора признаков (названия оригинальные, как в исходных наборах данных; типы признаков преобразованы к подходящим):
|
Признак |
Тип |
Описание |
|
Overall rank |
int |
Место страны в мировом рейтинге счастья (1 — самая счастливая). Рассчитывается на основе итогового Score |
|
Country or region |
object |
Название страны или региона |
|
Score |
float |
Итоговый индекс счастья — композитная метрика, отражающая субъективную оценку качества жизни населением |
|
GDP per capita |
float |
ВВП на душу населения |
|
Social support |
float |
Уровень социальной поддержки |
|
Healthy life expectancy |
float |
Ожидаемая продолжительность здоровой жизни |
|
Freedom to make life choices |
float |
Оценка свободы принимать жизненные решения (работа, место жительства, образ жизни) |
|
Generosity |
float |
Уровень щедрости: склонность населения к благотворительности и помощи другим |
|
Perceptions of corruption |
float |
Восприятие коррупции в государстве и бизнесе. Чем выше значение, тем ниже ощущаемый уровень коррупции |
|
Official language |
object |
Официальный язык страны |
|
Land Area(Km2) |
int |
Площадь страны в квадратных километрах |
|
Density (P/Km2) |
int |
Плотность населения (число человек на квадратный километр) |
|
Total tax rate |
float |
Общая налоговая ставка в процентах |
|
Unemployment rate |
float |
Уровень безработицы в процентах |
|
Population |
int |
Численность населения страны |
|
Urban_population |
int |
Численность городского населения |
Импорты и библиотеки, которые нам понадобятся:
import pandas as pdimport plotly.express as pximport plotly.graph_objects as go
Сразу проведем feature engineering и создадим несколько признаков, которые пригодятся для последующих визуализаций:
# группировка официальных языков (6 самых частых)top_languages = data['Official language'].value_counts().nlargest(6).index.tolist()data['Language_group'] = data['Official language'].map( lambda x: x if x in top_languages else 'Other')# создаем категории уровней - понадобится для многих графиков# сначала выделим те, для которых нужны отдельные правилаdata['Freedom_level'] = pd.qcut(data['Freedom to make life choices'], q=5, labels=['Super low', 'Low', 'Medium', 'High', 'Super high'])data['Corruption_level'] = pd.qcut(data['Perceptions of corruption'], q=3, labels=['High corrup', 'Medium corrup', 'Low corrup'])# соответствие для оставшихся с q=3features = { 'Healthy life expectancy': ('Healthy_life_level', 'HL'), 'Total tax rate': ('Total_tax_rate_level', 'TR'), 'Score': ('Happiness_level', 'Score'), 'Generosity': ('Generosity_level', 'GR'), 'Unemployment rate': ('Unemployment_rate_level', 'Unempl'),}for col, (new_col, suffix) in features.items(): labels = [f'Low {suffix}', f'Medium {suffix}', f'High {suffix}'] data[new_col] = pd.qcut(data[col], q=3, labels=labels)
Техническую подготовку завершили, переходим к самому интересному!
1. Bubble chart
Bubble chart, или пузырьковая диаграмма — это расширенная версия классического scatter plot, где к двум осям добавляется еще одно измерение — размер маркера.
Сразу рассмотрим пример, построенный по нашему датасету: проверим связь уровня счастья (Score), ВВП на душу населения (GDP per capita) и численности населения (Population):

Связь уровня счастья, ВВП на душу населения и численности
На графике хорошо прослеживается положительная линейная зависимость ВВП и счастья: по мере роста GDP per capita увеличивается и Score — в целом, это классический и ожидаемый макроэкономический паттерн.
Размер пузырька здесь отражает численность населения: самые крупные пузыри принадлежат Индии и Китаю. Однако четкой зависимости между численностью населения и уровнем счастья не прослеживается: мелкие и средние пузырьки разбросаны по всей области; разве что видим самые крупные государства посередине.
Это пример того, как третий фактор можно быстро проверить на значимость визуально. При желании можно еще сделать раскраску в разрезе какого-нибудь признака — тогда будет визуализация уже для 4 факторов. Например, дополним предыдущий график информацией об официальном языке (возьмем только 6 самых распространенных по количеству стран):

Связь уровня счастья, ВВП на душу населения, численности и официального языка
И снова не видим однозначной зависимости: языковые группы перемешаны, четких языковых облаков нет. Поэтому делаем осторожный вывод: сам по себе официальный язык не объясняет уровень счастья без учета экономических и социальных факторов.
Код и лайфхаки
В Plotly bubble chart строится через функцию scatterplot, а признак для размера пузырька задается в аргументе size. Библиотека масштабирует значения автоматически, но максимальный диаметр регулируется через size_max — используйте его, чтобы крупные объекты не перекрывали половину графика. Признак для раскраски всегда в Plotly записывается в color:
fig = px.scatter( data, x="GDP per capita", y="Score", size="Population", color="Language_group", hover_name="Country or region", size_max=60, title="GDP vs Happiness, size=population, color=language")# подписи осей fig.update_layout( xaxis_title="GDP per capita", yaxis_title="Happiness Score")fig.show()
Если диапазон признака размера пузырька очень широкий, иногда имеет смысл его логарифмировать, иначе маленькие объекты станут почти невидимыми.
Итого, пузырьковая диаграмма расширяет scatter plot, наглядно отображая масштаб и вес объектов через размер точек. Она идеально подходит для сравнения рынков, оценки портфеля и анализа влияния размера бизнеса на метрики.
2. Treemap
Treemap — это иерархическая диаграмма, где данные отображаются в виде вложенных прямоугольников. Площадь каждого лоскутка пропорциональна значению выбранного признака, а цвет добавляет еще одно измерение.
В отличие от bar chart, где мы сравниваем длины столбцов, treemap позволяет уместить десятки категорий в одном поле и сразу оценить их вклад в общий объем.
Сразу к примеру из нашего датасета: в качестве иерархии берем страны, размер прямоугольника кодирует плотность населения (Density), а цвет — уровень счастья (Score).

Связь размера страны и плотности населения с уровнем счастья
На визуализации мгновенно выделяются страны с экстремально высокой плотностью: они занимают самые крупные области. При этом treemap удобен тем, что даже небольшие государства остаются видимыми — просто в виде маленьких сегментов, а благодаря интерактивности можно рассмотреть даже самые маленькие квадратики.
Однако, если посмотреть на раскраску, можно заметить, что четкой зависимости между плотностью населения и счастьем нет. Среди крупных лоскутов встречаются как ярко-желтые (высокий Score), так и темно-синие (низкий Score). Та же картина наблюдается и среди небольших стран.
Это хороший пример ситуации, когда фактор кажется значимым интуитивно, но визуализация быстро показывает отсутствие устойчивой связи.
Код и лайфхаки
Код на Python достаточно простой, для этого графика есть отдельная функция:
fig = px.treemap( data, path=["Country or region"], values="Density\n(P/Km2)", color="Score", color_continuous_scale="Viridis", title="Density & score by countries")fig.show()
Сейчас мы указали только один признак в path, но можно добавлять их несколько — тогда увидите вложенные зависимости: в каком порядке перечислите признаки в списке для path, в такой же последовательности они будут группировать лоскутки на графике.
Именно поэтому treemap особенно полезен, когда нужно наглядно представить иерархию и профиль каждой группы: например, структуру дерева категорий или сравнить вклад стран/регионов, продуктов или сегментов — в наших данных не было таких показательных иерархических признаков.
Главное правило — не перегружать график. Слишком глубокая вложенность превращает его в мозаику, которую невозможно читать. Оптимально — 1–2 уровня иерархии плюс цвет как дополнительное измерение для наглядности.
3. Heatmap
Heatmap, или тепловая карта — это, по сути, раскрашенная таблица, где цвет ячеек отражает значение метрики согласно градиентной шкале.
Для таблицы свойственно две оси измерения, поэтому на практике тепловая карта чаще всего строится на основе pivot table либо какой-нибудь матрицы (например, корреляций). Важно, чтобы было две дискретные оси и агрегированная метрика в ячейках.
Давайте проанализируем, как уровень счастья зависит от ожидаемой продолжительности здоровой жизни (Healthy life expectancy) и свободы принимать жизненные решения (Freedom to make life choices). После построения такой сводной таблицы каждая ячейка покажет средний Score для соответствующей комбинации признаков.

Связь уровня счастья с ожидаемой продолжительностью здоровой жизни и свободой принимать жизненные решения
Читается heatmap интуитивно: по оси X — уровни свободы, по оси Y — уровни здоровой жизни, а цвет — средний уровень счастья, шкала-легенда представлена справа.
И здесь уже проявляется отчетливая зависимость:
● в нижнем правом секторе (где одновременно высокая продолжительность здоровой жизни и высокое ощущение свободы) наблюдаются самые темные насыщенные оттенки — то есть максимальные значения счастья;
● в противоположной зоне (при низких значениях обоих факторов) цвет заметно бледнее, что указывает на более низкий Score.
Код и лайфхаки
Таким образом, тепловая карта позволяет увидеть не просто влияние отдельных факторов, а их совместный эффект. Это крайне полезный график для наглядного представления сводных таблиц, исследования связи факторов, визуализации матрицы корреляций, анализа retention, churn, конверсии, результатов A/B-тестов по сегментам и т. д.
pivot = data.pivot_table( index="Healthy_life_level", columns="Freedom_level", values="Score", aggfunc="mean")fig = px.imshow( pivot, text_auto=True, color_continuous_scale="Blues", title="Mean Score on Healthy life expectancy & Freedom to make life choices")fig.show()
Практический совет — следить за количеством категорий или бинов в признаках по осям. Слишком большое число разрезов делает карту нечитаемой, опять-таки превращая ее в бесполезную мозаику.
4. Sankey
Sankey diagram — это график потоков, который показывает, как объекты распределяются между категориями на разных этапах. Его ключевая идея — визуализировать не сами значения признаков, а переходы между состояниями.
Ширина лент здесь играет роль: чем она больше, тем больше наблюдений попало в соответствующий переход. За счет этого sankey отлично подходит для анализа многошаговых зависимостей, сегментаций, пользовательских воронок, путей клиентов или любых последовательных распределений.
В нашем датасете нет таких явных цепочек, но давайте для примера рассмотрим такую последовательность:
Happiness → Generosity → Total tax rate
То есть как страны с разным уровнем счастья распределяются по уровням щедрости, а затем — по налоговой нагрузке.

Связь уровня счастья со щедростью государства и налоговой нагрузкой
Как читать такую картинку?
Левая половина диаграммы показывает переходы от уровня счастья к уровню щедрости:
● Видно, что из группы стран с высоким уровнем счастья заметная доля уходит в высокую щедрость — поток здесь один из самых широких. Значит, более счастливые страны чаще демонстрируют более высокий уровень щедрости.
● Страны с низким уровнем счастья распределяются иначе: значительная часть потоков уходит в низкую и среднюю щедрость — это указывает на менее выраженные практики добровольной поддержки внутри общества.
● Средний уровень счастья, как правило, дает более равномерное распределение — без ярко выраженного доминирования одного уровня щедрости.
Таким образом, уже на первом шаге читается положительная ассоциация: чем выше субъективное благополучие, тем выше склонность к щедрости.
Правая половина диаграммы показывает следующий переход — от щедрости к налоговой нагрузке:
● Здесь появляется интересный эффект: страны с высокой щедростью чаще переходят в зоны низких и средних налогов, и это важное наблюдение — высокая социальная щедрость чаще сопровождается низкой фискальной нагрузкой.
● Обратная картина частично наблюдается для стран с низкой щедростью: от них заметная доля потоков уходит в более высокие налоговые ставки, это можно интерпретировать как большую роль государства в перераспределении ресурсов там, где частная щедрость выражена слабее. Но можно и продолжить зависимость, посмотрев на связь налоговой нагрузки и других признаков:)
Сквозной путь. Самое ценное в sankey — возможность читать не только соседние связи, но и полный маршрут:
● Если проследить сквозные потоки, становится заметен один из доминирующих путей (самая широкая полоса):
High happiness → High generosity → Low/Medium tax
Это означает, что значительная часть наиболее счастливых стран одновременно характеризуется высокой щедростью и умеренной или низкой налоговой нагрузкой.
● Другой, менее выраженный, но читаемый маршрут:
Low happiness → Low generosity → High tax
Он отражает страны, где субъективное благополучие ниже, частная щедрость слабее, а перераспределительная роль государства выше.
Важно подчеркнуть: sankey не показывает причинно-следственные связи. Он фиксирует распределения и переходы, но объясняет, что именно вызывает такую картину.
Код и лайфхаки
Первое — не перегружайте диаграмму: оптимально использовать 2–3 шага и ограниченное число категорий внутри каждого. Если уровней слишком много, график превращается в нечитаемую «лапшу», поэтому как минимум высококардинальные признаки предварительно категоризируют на low / medium / high, квантили или бины.
Второе — порядок признаков должен отражать логику процесса: от причины к следствию, от начала воронки к концу, от общего к частному. Ну или выбирайте более логичные признаки, как это попытались сделать мы.
Третье — важно работать с агрегированными значениями: sankey плохо читается на сырых данных, но отлично на сгруппированных переходах.
И наконец, помните, что это объяснительный, а не статистический инструмент. Он усиливает сторителлинг и презентацию, но не заменяет корреляционный или причинный анализ.
В части кода — для этого типа визуализации важно заранее подготовить данные для каждого потока, агрегировав нужные признаки:
# агрегация потоковsankey_data = ( data .groupby( ['Happiness_level', 'Total_tax_rate_level', 'Generosity_level'] ) .size() .reset_index(name='count'))# список уникальных узловlabels = list( pd.concat([ sankey_data['Happiness_level'], sankey_data['Total_tax_rate_level'], sankey_data['Generosity_level'] ]).unique())label_to_idx = {label: i for i, label in enumerate(labels)}# 1-я половинаsource = sankey_data['Happiness_level'].map(label_to_idx)target = sankey_data['Generosity_level'].map(label_to_idx)value = sankey_data['count']# 2-я половинаsource2 = sankey_data['Generosity_level'].map(label_to_idx)target2 = sankey_data['Total_tax_rate_level'].map(label_to_idx)value2 = sankey_data['count']# объединяемsources = pd.concat([source, source2])targets = pd.concat([target, target2])values = pd.concat([value, value2])
Далее код построения графика не займет много строк:
fig = go.Figure(data=[go.Sankey( node=dict( pad=15, thickness=20, line=dict(color="black", width=0.5), label=labels ), link=dict( source=sources, target=targets, value=values ))])fig.update_layout(title_text="Happiness -> Generosity -> Total_tax_rate", font_size=10)fig.show()
5. Sunburst
Sunburst — это иерархическая круговая диаграмма, которая показывает, как одна категория дробится на подкатегории на нескольких уровнях вложенности. Если sankey отвечает на вопрос: «Как объекты перетекают между состояниями?», то sunburst — на вопрос: «Из чего состоит структура внутри категории?».
Каждое кольцо здесь — новый уровень детализации: чем дальше от центра, тем глубже уровень иерархии. Размер сектора отражает объем, а цвет дополнительно кодирует величину показателя.
В нашем примере график будет показывать структуру счастья через двухуровневую иерархию:
Corruption level → Unemployment rate level

Связь уровня счастья с восприятием коррупции и безработицей
То есть сначала страны группируются по уровню восприятия коррупции, а затем внутри каждой группы — по уровню безработицы. Посмотрим, как это интерпретировать.
Первый уровень — коррупция. Центральное кольцо делит все страны на три крупные категории:
● Low corruption.
● Medium corruption.
● High corruption.
Размер каждого сектора показывает суммарный вклад стран этой группы в общий показатель счастья (Score):
● Уже на этом уровне видно, что сектор с низкой коррупцией чуть крупнее и окрашен в более светлые оттенки шкалы Viridis. Это означает более высокий средний уровень счастья в странах, где коррупция воспринимается как низкая.
● Секторы средней и высокой коррупции, напротив, темнее — индикатор более низких значений счастья.
Второй уровень — безработица внутри коррупции. Следующее кольцо показывает детализацию: как внутри каждой группы по признаку коррупции распределяются уровни безработицы.
Например, внутри Low corruption видим три сегмента: Low, Medium и High unemployment. Самый светлый из них — средняя безработица; это означает, что в странах с низкой коррупцией и средней безработицей суммарный уровень счастья максимален.
В группе High и Medium corruption картина обратная: даже при низкой безработице сегменты остаются сравнительно темными. Это подчеркивает, что высокий уровень коррупции сам по себе связан с более низким счастьем, независимо от занятости.
Сквозное чтение структуры. Хотя sunburst не показывает потоки, как sankey, он позволяет считывать вложенные сочетания факторов:
● Самый счастливый сегмент здесь: Low corruption → Medium unemployment.
● А самый несчастный: Medium corruption → High unemployment.
Таким образом, график наглядно демонстрирует кумулятивный эффект факторов: как негативные социально-экономические условия накладываются друг на друга.
Этот тип визуализации особенно хорош, когда нужно показать иерархическую декомпозицию метрики:
● структура выручки (категория → подкатегория → бренд);
● состав клиентской базы, причины оттока;
● разложение метрик качества;
● организационные структуры.
Он отлично работает там, где важна вложенность, но нет временной или потоковой логики.
Код и лайфхаки
На Python такой график рисуется недолго:
fig = px.sunburst( data, path=['Corruption_level', 'Unemployment_rate_level'], values='Score', color='Score', color_continuous_scale='Viridis', title="Happiness: Corruption -> Unemployment")fig.show()
Как всегда, не стоит переусердствовать и добавлять слишком много уровней: оптимум — 2–3 кольца, дальше диаграмма теряет читаемость.
Также важно правильно выбирать метрику в values, так как от этого напрямую зависит интерпретация площади сегментов. Как правило, берут таргет. Плюс для наглядности можете использовать его же в качестве раскраски, хотя можно брать и другой признак. Главное — не перейти порог перегруженности.
6. Radar chart
Radar chart, или паучья диаграмма — это способ одновременно сравнить несколько количественных признаков для разных групп объектов.
Если scatter показывает связь двух переменных, а heatmap — интенсивность на пересечении осей, то radar отвечает на другой аналитический вопрос: «Как выглядит профиль объекта или сегмента сразу по набору факторов?».
Каждая ось, расходящаяся от центра, — это отдельный признак. Значение откладывается по радиусу: чем дальше от центра, тем оно выше. Соединяя точки по осям, мы получаем многоугольник — форму профиля.
В нашем случае сравним средние значения факторов счастья для трех групп стран: Low, Medium, High. Оси — это ключевые драйверы счастья, возьмем в качестве них сразу несколько признаков:
● GDP per capita.
● Social support.
● Healthy life expectancy.
● Freedom to make life choices.
● Generosity.
● Perceptions of corruption.

Среднее значение факторов счастья для трех групп стран
Первое, что бросается в глаза — площадь многоугольников:
● Профиль стран с высоким уровнем счастья занимает наибольшую площадь почти по всем осям — это означает, что высокие значения Score системно сопровождаются более высокими социально-экономическими показателями.
● Профиль Low Score, напротив, сжат ближе к центру — индикатор более низких значений.
● А Medium Score ожидаемо находится между ними, формируя переходную форму.
Практически по всем осям сохраняется монотонность, кроме Generosity: если присмотреться, уровень щедрости в группе Low Score немного выше, чем в Medium Score. Возможно, фактор щедрости отчасти культурно обусловлен и не всегда связан с экономическим благополучием — а тем самым и с уровнем счастья. Но при этом High Score все равно демонстрирует максимальные значения generosity — то есть в верхнем сегменте связь возвращается.
Код и лайфхаки
Итого, radar chart здесь показывает не отдельные зависимости, а комплексный профиль благополучия. Этот тип визуализации особенно полезен, когда нужно сравнить сегменты клиентов, показать профиль продукта или skill-profile команд, визуализировать результаты опросов. Также график очень помогает для интерпретации в задаче кластеризации.
В Python потребуется предварительная группировка значений для визуализации по осям:
categories = [ "GDP per capita", "Social support", "Healthy life expectancy", "Freedom to make life choices", "Generosity", "Perceptions of corruption"]radar_data = data.groupby("Happiness_level")[categories].mean().reset_index()
Для построения графика необходим модуль go:
fig = go.Figure()for i, row in radar_data.iterrows(): fig.add_trace(go.Scatterpolar( r=row[categories].values, theta=categories, fill='toself', name=row["Happiness_level"] ))fig.update_layout( polar=dict( radialaxis=dict(visible=True) ), title="Average Factors by Happiness Level")fig.show()
Совет по построению прежний: не стоит перегружать диаграмму большим количеством осей и групп, оптимально — 5-8 признаков и 3-5 групп максимум. Также важно учитывать масштаб: в базовом виде, как в нашем примере, значения отображаются в исходных единицах; если признаки сильно различаются по диапазонам, их лучше нормализовать — иначе доминирующие оси «сплющат» остальные.
7. Choropleth
И наконец, последний и очень эффектный тип визуализации для демонстраций в разрезе географии. В отличие от всех предыдущих графиков здесь информация накладывается непосредственно на карту: страны или регионы закрашиваются в зависимости от значения показателя. За счет этого мы сразу видим пространственные паттерны, которые трудно уловить в таблицах или scatter-диаграммах.
Вот как выглядит раскраска карты мира в соответствии с тепловой шкалой уровня счастья (Score):

Тепловая шкала уровня счастья в мире
Каждая страна окрашена в свой цвет по правилу, поэтому буквально за несколько секунд можно уловить глобальные зависимости:
● страны Северной Европы и часть Западной Европы формируют зону с высокими значениями счастья — они выделяются наиболее насыщенными цветами;
● напротив, ряд стран Африки и Южной Азии окрашены в более темные тона, что указывает на более низкие значения показателя.
Главное преимущество choropleth — возможность увидеть региональные закономерности. Мы начинаем мыслить не отдельными странами, а макрорегионами. При этом внутри регионов тоже видны различия — карта помогает быстро находить выбросы и страны, которые сильно отличаются от соседей.
Код и лайфхаки
Важно понимать, что choropleth показывает именно распределение по территории, а не силу статистической зависимости, поэтому его хорошо использовать в связке с другими графиками: сначала увидеть географический паттерн, затем проверить конкретную гипотезу на scatter plot или heatmap.
Технически для построения choropleth нужны ISO-коды (можно взять через pycountry) или стандартные названия стран — у нас как раз имеется последнее:
fig = px.choropleth( data, locations="Country or region", # или "iso_alpha" если есть locationmode="country names", # "ISO-3" если используем ISO коды color="Score", hover_name="Country or region", color_continuous_scale=px.colors.sequential.Viridis, title="World Happiness Score by Country")fig.show()
Из практических советов: аккуратно подбирайте цветовую шкалу, слишком контрастные палитры искажают восприятие, а слишком бледные скрывают различия. И следите за нормализацией метрики: абсолютные показатели (например, общий ВВП) на карте часто вводят в заблуждение, поэтому предпочтительнее использовать относительные значения — на душу населения, в процентах и т. д.
Стили и дизайн графиков
Стилизация и дизайн — это финальный слой работы с визуализацией, который превращает «просто график» в презентационный инструмент. В большинстве библиотек (в том числе Plotly) можно модифицировать практически все: цветовые шкалы, шрифты, подписи, прозрачность, границы сегментов, легенды, hover-подсказки, отступы, фон, формат заголовков и даже геометрию элементов. Грамотная стилизация помогает управлять вниманием зрителя: усиливать контраст ключевых зон, приглушать второстепенные, выравнивать композицию и делать график читаемым на слайдах или в отчете.
Рассмотрим это на примере нашего sunburst. Ниже — тот же график, но с некоторыми доработками: усилим контраст, настроим фон, шрифты, границы сегментов и подписи.
fig = px.sunburst( data, path=['Corruption_level', 'Unemployment_rate_level'], values='Score', color='Score', color_continuous_scale='RdYlGn', # более контрастная шкала title="Happiness: Corruption → Unemployment")fig.update_traces( textinfo="label+percent entry", # подписи + доли insidetextorientation="radial", marker=dict( line=dict(color="white", width=2) # границы сегментов ), hovertemplate=( "<b>%{label}</b><br>" "Score: %{value:.2f}<br>" "Share: %{percentEntry:.1%}<extra></extra>" ))fig.update_layout( title_font_size=22, title_x=0.5, font=dict(family="Arial", size=12), margin=dict(t=80, l=20, r=20, b=20), paper_bgcolor="#F9F9F9", # фон всей области plot_bgcolor="#F9F9F9", coloraxis_colorbar=dict( title="Score", tickfont=dict(size=10) ))fig.show()
График стал более наглядным и чистым, дефолтный ploty-стиль уже почти не прослеживается. Готовьтесь удивить коллег тем, что все это по-прежнему построено в Python:)

Улучшенный визуально график sunburst
И снова-таки главный принцип стилизации — умеренность. Не стоит одновременно использовать пестрые палитры, жирные шрифты, толстые границы и сложные подписи, иначе график станет слишком декоративным, рискуя потерять аналитическую ценность. Хороший дизайн должен быть незаметен — он не отвлекает, а помогает быстрее увидеть вывод.
Вредные советы
Мы уже разобрали много рекомендаций для разных типов графиков и, возможно, вы заметили общий мотив: почти все они сводятся к одному и тому же принципу — не перегружать визуализацию.
В погоне за красотой и желанием наполнить график как можно большим количеством полезной информации не забывайте, что хорошая визуализация упрощает понимание данных, а плохая — делает ровно наоборот: зритель тратит время не на выводы, а на расшифровку того, что вообще изображено.
Еще раз обозначим чек-лист:
● на графике не должно быть избыточного количества элементов;
● цвета не должны конфликтовать друг с другом;
● подписи должны оставаться читаемыми;
● легенда не должна превращаться в отдельную простыню;
● а сам график должен доносить 1–2 ключевых мыслей, а не десять сразу.
В качестве плохих примеров оставлю здесь несколько графиков, которые перестали выполнять свою ключевую роль — попробуйте расшифровать, что хотел сказать автор:)



Заключение
Визуализация данных — это не украшение отчета, а инструмент мышления и коммуникации. Это язык, на котором аналитик разговаривает с бизнесом, командой и самим собой, когда исследует данные, ищет закономерности и формулирует выводы.
Вам не обязательно становиться дизайнером или изучать теорию цвета на академическом уровне, чтобы делать сильные графики. Но понимание базовых принципов — как работает внимание зрителя, зачем упрощать форму, почему важен фокус и иерархия элементов — позволяет создавать не просто красивые, а эффективные визуализации, которые ускоряют принятие решений, а не тормозят его.
А главное — вы начинаете видеть в графиках не набор линий и столбцов, а управляемый инструмент, через который можно точно доносить смысл, акценты и инсайты из данных.
ссылка на оригинал статьи https://habr.com/ru/articles/1029978/