Heatmap и матрицы: когда цвет уместен

Тепловая карта превращает матрицу чисел в поле цвета — удобно для обзора, опасно для точных значений.

Heatmap (тепловая карта) — представление двумерной таблицы значений цветом ячеек, где цвет кодирует величину. Подходит для обзора структуры матрицы (корреляции, сходства, частоты).

Где heatmap силён

Когда у вас матрица — корреляционная, матрица расстояний, таблица сопряжённости двух категорий, поле значений по сетке (x, y) — глазами читать числа невозможно, а цветовое поле сразу показывает узор: блоки похожих значений, диагональ, «горячие» точки. Классика — корреляционная матрица признаков: тёплые клетки = сильная корреляция, и кластеры коррелирующих признаков видны как цветные блоки.

Цена цвета как канала

Но помните иерархию каналов: цвет — слабый канал для измерения. По heatmap нельзя точно прочитать «0,73» — только грубо «тёплое, около 0,7». Поэтому heatmap хорош для обзора и поиска узора, но если важны точные значения, дублируйте их числом в ячейке или замените на точечный график. И обязательно нужна цветовая шкала (colorbar) — без неё цвет ничего не значит.

Нормировка решает всё

Heatmap честен только при правильной нормировке. Если в матрице одно значение 1000, а остальные около 1, то вся карта будет одного цвета с единственной яркой точкой — структура потеряется. Решения: логарифмировать значения, обрезать выбросы (clip) или нормировать по строкам/столбцам. Для расходящихся данных (корреляция от $-1$ до $+1$) центр шкалы должен быть на нуле — об этом подробно в разделе про цвет.

Нормируем матрицу сами

Подготовим маленькую матрицу к heatmap: приведём значения к диапазону $[0, 1]$ построчной мин-макс нормировкой, чтобы цвет показывал относительную величину внутри строки.

matrix = [
    [2, 8, 4],
    [10, 20, 15],
    [1, 1, 100],
]

def row_minmax(row):
    lo, hi = min(row), max(row)
    if hi == lo:
        return [0.0 for _ in row]
    return [round((v - lo) / (hi - lo), 2) for v in row]

for r in matrix:
    print(r, "->", row_minmax(r))

Вывод:

[2, 8, 4] -> [0.0, 1.0, 0.33]
[10, 20, 15] -> [0.0, 1.0, 0.5]
[1, 1, 100] -> [0.0, 0.0, 1.0]

Теперь в каждой строке минимум станет одним краем шкалы, максимум — другим, и структура внутри строки читается, несмотря на разный масштаб строк.

ASCII-набросок heatmap

     c1   c2   c3        легенда:
r1 [ .    #    : ]        .  низкое
r2 [ .    #    o ]        :  среднее
r3 [ .    .    # ]        o  высокое
                         #  максимум

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

Heatmap — это отображение скаляра в цвет через цветовую карту (colormap): функция, переводящая число из диапазона данных в RGB. Качество карты зависит от того, монотонно ли растёт воспринимаемая яркость вдоль шкалы (см. урок про viridis). Часто к heatmap добавляют кластеризацию: строки и столбцы переупорядочивают так, чтобы похожие оказались рядом — тогда блочная структура проявляется (это clustermap).

Порядок строк и столбцов — это данные

Heatmap с произвольным порядком строк и столбцов часто выглядит как случайный шум, даже когда в данных есть чёткая структура. Решение — переупорядочить строки и столбцы так, чтобы похожие оказались рядом. Для корреляционных матриц это делают иерархической кластеризацией: похожие признаки группируются, и на карте проявляются цветные блоки — кластеры взаимосвязанных переменных. Такой график называют clustermap, и к нему сбоку рисуют дендрограмму, показывающую, как именно сгруппированы строки.

Это частный случай общего принципа: порядок категорий на любом графике — носитель информации, а не формальность. Отсортированные по значению столбцы читаются лучше алфавитных; упорядоченные по сходству строки heatmap выявляют структуру; разумно расставленные панели small multiples показывают градиент. Прежде чем оставить порядок «как пришло из таблицы», спросите: не несёт ли осмысленная сортировка дополнительный смысл?

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

  • Heatmap без colorbar — цвет нечем интерпретировать.
  • Радужная палитра — создаёт ложные границы (см. урок про цвет).
  • Выброс губит шкалу — одна большая ячейка делает остальное одноцветным; логарифмируйте или обрезайте.
  • Чтение точных чисел по цвету — цвет даёт лишь грубую оценку; дублируйте числом.

Итог

  • Heatmap хорош для обзора структуры матрицы, не для точных значений.
  • Всегда нужна цветовая шкала.
  • Нормировка и обработка выбросов критичны.
  • Кластеризация строк/столбцов проявляет блочную структуру.
Проверьте себя
1. Для чего лучше всего подходит heatmap?
AДля точного чтения отдельных значений
BДля обзора структуры матрицы: корреляций, блоков, узоров
CДля показа динамики во времени
DДля сравнения двух чисел
2. Почему один большой выброс портит heatmap?
AОн замедляет рендеринг
BОн растягивает цветовую шкалу, и все остальные ячейки становятся почти одноцветными
CОн меняет форму ячеек
DОн удаляет легенду
3. Что обязательно должно сопровождать heatmap?
A3D-эффект
BЦветовая шкала (colorbar), связывающая цвет со значением
CЛиния тренда
DКруговая вставка