Дашборды и интерактивные отчёты

Дашборд — это не свалка графиков, а навигируемая история. Несколько связанных панелей, отвечающих на конкретные вопросы.

«Хороший дашборд отвечает на пять вопросов с одного экрана. Плохой — задаёт пятьдесят».

Дашборд собирает несколько графиков на один экран, чтобы дать целостную картину: KPI сверху, динамика, разбивка по категориям, детали. Plotly умеет компоновать панели через make_subplots, добавлять интерактивные элементы — фильтры, слайдеры, кнопки.

Чтобы дашборд работал, у него должна быть драматургия чтения, а не просто плотная упаковка графиков. Хорошая раскладка следует естественному маршруту взгляда: сверху и слева — самые агрегированные числа (итоговые KPI и главный тренд), отвечающие на вопрос «как дела в целом?»; ниже и правее — разбивки и детали, отвечающие на «а почему именно так и где конкретно?». Этот переход от общего к частному называют принципом «обзор сначала, детали по запросу»: зритель сперва ловит общую картину, а затем спускается к причинам. Если же все панели одинаково детальны и равнозначны, глазу не за что зацепиться, и дашборд читается как стена шума.

Стоит различать два класса дашбордов, потому что требования к ним разные. Аналитический (exploratory) дашборд предназначен для самостоятельного исследования: здесь уместны фильтры, слайдеры по датам, связанные выделения, переключатели метрик — пользователь сам задаёт вопросы. Отчётный (explanatory) дашборд, наоборот, ведёт читателя по заранее выстроенному выводу, и лишний интерактив тут только отвлекает: его задача — чтобы с одного взгляда стало ясно главное. Прежде чем добавлять очередной слайдер, спросите себя, какой из двух дашбордов вы строите.

from plotly.subplots import make_subplots
import plotly.graph_objects as go

fig = make_subplots(rows=2, cols=2,
                    subplot_titles=("Динамика", "По регионам",
                                    "Распределение", "Доли"))

fig.add_trace(go.Scatter(x=days, y=revenue), row=1, col=1)
fig.add_trace(go.Bar(x=regions, y=sales),    row=1, col=2)
fig.add_trace(go.Histogram(x=values),        row=2, col=1)
fig.add_trace(go.Pie(labels=names, values=shares), row=2, col=2)

fig.update_layout(height=700, title_text="Сводный дашборд продаж",
                  showlegend=False)
fig.show()
МАКЕТ ДАШБОРДА — слева направо, сверху вниз
   +-----------------+-----------------+
   |  KPI / динамика | сравнение       |
   |  (line)         | (bar)           |
   +-----------------+-----------------+
   | распределение   | состав          |
   | (histogram)     | (pie/stacked)   |
   +-----------------+-----------------+
   главное -> вверху-слева (туда смотрят первым)

Как работает под капотом

make_subplots резервирует сетку доменов (областей) внутри одной фигуры и привязывает каждый трейс к ячейке (row, col). Все панели остаются частью единого JSON, поэтому интерактив (зум, hover) работает в каждой. Слайдеры и кнопки добавляют в layout элементы управления, которые через frames меняют видимые данные — это и есть основа анимаций и фильтров.

Для KPI-плашек дашборда часто считают агрегаты и дельту к прошлому периоду. Сделаем это руками.

# KPI для верхней плашки дашборда: итог, среднее, дельта к прошлому периоду
this_month = [120, 135, 150, 190, 175, 160]
prev_month = [110, 130, 140, 160, 170, 150]

total = sum(this_month)
avg = total / len(this_month)
prev_total = sum(prev_month)
delta_pct = (total - prev_total) / prev_total * 100

print("Итого:", total)
print("Среднее в день:", round(avg, 1))
print("Динамика к прошлому месяцу: {:+.1f}%".format(delta_pct))

«Попробуй сам ▶» — итог, среднее и дельта в процентах — это типичные числа для KPI-карточек в верхней части дашборда.

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

Слишком много панелей — когнитивная перегрузка (правило: 4–6 на экран). Разные шкалы и палитры в одном дашборде — рассогласование. Нет иерархии: главное не выделено. Интерактив ради интерактива — слайдеры, которые никто не двигает. Отсутствие заголовков-выводов на панелях.

Самый коварный из этих промахов — рассогласование шкал. Если одна панель измеряет выручку в тысячах, а соседняя в миллионах, или у двух гистограмм разные диапазоны оси Y, зритель невольно сравнивает высоты столбиков напрямую и делает ложные выводы. Поэтому панели, которые предполагается сравнивать, должны делить общую шкалу: в make_subplots для этого есть параметры shared_xaxes и shared_yaxes. Та же дисциплина касается цвета: одна категория (например, регион «Север») должна быть одного и того же цвета на всех панелях, иначе легенда перестаёт работать как единый ключ.

Ещё две ошибки связаны с восприятием, а не с кодом. Первая — смешивать в одной сетке несочетаемые типы графиков (круговую диаграмму рядом с тепловой картой и временным рядом) без логической группировки: глаз не понимает, как они связаны. Вторая — забывать про «пустое место»: новички стремятся заполнить каждый пиксель, но плотно упакованный дашборд читается тяжелее разреженного. Воздух между панелями — это не потраченное место, а инструмент, который отделяет смысловые блоки и снижает нагрузку на внимание.

Best practices

  • Самое важное — в левый верхний угол (туда смотрят первым).
  • 4–6 панелей максимум; группируйте логически.
  • Единая палитра и шкалы по всему дашборду.
  • Заголовок-вывод на каждой панели, а не просто «График 1».

Итог: вы умеете собирать дашборд. Финальный раздел — принципы, которые отличают честную визуализацию от манипуляции.

Проверьте себя
1. Куда помещают самую важную панель дашборда?
AВ правый нижний угол
BВ левый верхний угол
CВ центр поверх остальных
DНе имеет значения
2. Сколько панелей разумно держать на одном экране дашборда?
A20 и больше
BОдну
CПримерно 4–6
DРовно 10