Расходящийся масштаб: d3.scaleDiverging()

В библиотеке D3.js масштабирование данных реализуется через набор функций, преобразующих числовые значения в визуальные представления: цвет, координаты, размеры. Расходящийся масштаб (diverging scale) предназначен для отображения данных, у которых есть средняя точка (нейтральное значение), относительно которой значения расходятся в противоположные стороны.

Типичные сценарии применения:

  • отклонения от нуля (температурные аномалии, финансовые изменения);
  • корреляции и коэффициенты;
  • разности между двумя состояниями;
  • любые данные с выраженным «центром».

Концепция расходящегося масштаба

Расходящийся масштаб интерпретирует числовую шкалу как симметричное пространство вокруг центрального значения.

Основная идея:

  • левый край → отрицательные/уменьшающиеся значения
  • центр → нейтральное значение
  • правый край → положительные/увеличивающиеся значения

В отличие от линейных или логарифмических масштабов, здесь важна визуальная симметрия относительно центра, а не равномерность интервалов.


Базовый синтаксис

d3.scaleDiverging(interpolator)

Где:

  • interpolator — функция интерполяции, определяющая переход между цветами или значениями;
  • возвращаемое значение — функция масштаба.

Простейший пример:

const scale = d3.scaleDiverging(d3.interpolateRdBu);

Интерполяция и роль центра

Расходящийся масштаб работает через параметр t в диапазоне [0, 1].

Интерпретация:

  • t = 0 → край «отрицательной» стороны
  • t = 0.5 → центр
  • t = 1 → край «положительной» стороны

Используемые интерполяторы:

  • d3.interpolateRdBu
  • d3.interpolatePiYG
  • d3.interpolateRdYlBu
  • кастомные функции интерполяции

Настройка домена

По умолчанию масштаб использует домен:

[0, 1]

Однако в реальных задачах почти всегда задаётся трёхточечный домен:

d3.scaleDiverging()
  .domain([-100, 0, 100])

Интерпретация:

  • -100 → край отрицательных значений
  • 0 → центр
  • 100 → край положительных значений

Центральное значение не обязано быть нулём:

d3.scaleDiverging()
  .domain([10, 50, 200])

Внутренний принцип преобразования

Масштаб выполняет нормализацию входного значения в интервал [0, 1] с учётом центра:

  • значения ниже центра масштабируются в диапазон [0, 0.5]
  • значения выше центра — в [0.5, 1]

Формально:

  • левая часть: линейная интерполяция от min до mid
  • правая часть: от mid до max

Это позволяет добиться визуально сбалансированного перехода.


Цветовые шкалы

Наиболее частое применение — цветовое кодирование отклонений.

Пример тепловой карты:

const color = d3.scaleDiverging()
  .domain([-1, 0, 1])
  .interpolator(d3.interpolateRdBu);

Использование:

color(-0.8); // синий оттенок
color(0);    // нейтральный цвет
color(0.8);  // красный оттенок

Такой подход широко применяется в:

  • климатических визуализациях;
  • анализе ошибок моделей;
  • финансовых графиках.

Применение в визуализации данных

Карты отклонений

const temperatureScale = d3.scaleDiverging()
  .domain([-30, 0, 30])
  .interpolator(d3.interpolateRdYlBu);

Каждое значение температуры отображается относительно нуля как центра.


Анализ ошибок модели

const errorScale = d3.scaleDiverging()
  .domain([-1, 0, 1])
  .interpolator(d3.interpolatePuOr);
  • отрицательные ошибки → один цвет
  • положительные → противоположный
  • ноль → нейтральный

Отличие от линейного масштаба

Характеристика Линейный масштаб Расходящийся масштаб
Центр не учитывается обязателен
Симметрия отсутствует ключевая особенность
Интерполяция равномерная двухсторонняя
Основное применение оси, координаты отклонения, разности

Кастомные интерполяторы

Можно задавать собственную функцию:

const scale = d3.scaleDiverging(t => {
  return d3.interpolateCool(t);
});

Или более сложный вариант:

const scale = d3.scaleDiverging(t => {
  return t < 0.5
    ? d3.interpolateBlues(t * 2)
    : d3.interpolateReds((t - 0.5) * 2);
});

Это позволяет вручную контролировать поведение центра и контраст.


Работа с числовыми значениями вне домена

Если значение выходит за пределы домена, поведение определяется интерполятором:

  • значения меньше минимума «прижимаются» к краю;
  • значения больше максимума также ограничиваются.

Пример:

scale(-200); // крайнее левое значение
scale(200);  // крайнее правое значение

Инверсия масштаба

Как и другие масштабы D3, расходящийся масштаб поддерживает инверсию:

scale.invert(value);

Это позволяет получить исходное числовое значение из визуального представления.


Типичные ошибки при использовании

  • отсутствие корректного центра в домене;
  • использование неподходящего интерполятора (без контраста);
  • несбалансированные диапазоны (например, [-1, 0, 100]);
  • попытка использовать масштаб для категориальных данных.

Практическая структура применения

Расходящийся масштаб обычно интегрируется в:

  • оси (d3.axis);
  • заливку SVG-элементов;
  • стили CSS через JS;
  • цветовые легенды.

Пример интеграции:

svg.selectAll("rect")
  .data(data)
  .enter()
  .append("rect")
  .attr("fill", d => color(d.value));

Поведение с непрерывными данными

Масштаб рассчитан на непрерывные значения, где:

  • важна относительная разница;
  • центр имеет смысловую нагрузку;
  • визуальное восприятие важнее точной арифметики.

Он плохо подходит для:

  • дискретных категорий;
  • бинарных значений;
  • нечисловых данных.