Квантовый и квантильный масштабы: scaleQuantize, scaleQuantile

Квантование в визуализации данных применяется для преобразования непрерывных или высокоразмерных значений в дискретные категории. В D3.js для этого используются два ключевых механизма: scaleQuantize и scaleQuantile. Несмотря на схожую цель — разбиение числового диапазона на классы — их поведение принципиально различается.


Квантовая шкала scaleQuantize выполняет разбиение непрерывного входного диапазона на равные интервалы и сопоставляет каждому интервалу фиксированное выходное значение.

Формально:

  • вход: непрерывное множество чисел
  • выход: конечное число дискретных значений
  • принцип: равные интервалы по оси входных данных

Базовая структура

const scale = d3.scaleQuantize()
  .domain([0, 100])
  .range(["low", "medium", "high"]);

Здесь диапазон [0, 100] делится на три равные части:

  • 0–33.33 → “low”
  • 33.33–66.66 → “medium”
  • 66.66–100 → “high”

Особенности распределения

Количество интервалов определяется длиной range. Если в range три элемента, создаётся три равных сегмента.

Каждый входной элемент преобразуется через линейное разбиение:

  • шаг интервала = (max − min) / n

где n — количество значений в range.

Пример применения в цветовой кодировке

const colorScale = d3.scaleQuantize()
  .domain([0, 1000])
  .range(["#d4eeff", "#74c0fc", "#1c7ed6"]);

console.log(colorScale(100));  // светлый цвет
console.log(colorScale(500));  // средний
console.log(colorScale(900));  // тёмный

Поведение на границах

Границы интервалов вычисляются автоматически и равномерно. Это приводит к следующему эффекту:

  • данные с неравномерным распределением могут попасть в перегруженные или пустые классы
  • шкала не учитывает статистику набора данных

Квантильная сегментация через scaleQuantile

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

В отличие от scaleQuantize, здесь:

  • интервалы не равны по диапазону
  • интервалы формируются по количеству элементов

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

Квантильная шкала стремится распределить данные так, чтобы:

  • в каждом классе было примерно одинаковое количество элементов

Это делает её особенно полезной для анализа распределений с перекосами.

Пример инициализации

const scale = d3.scaleQuantile()
  .domain([10, 20, 30, 40, 50, 60, 70, 80])
  .range(["Q1", "Q2", "Q3"]);

Здесь данные автоматически делятся на три группы:

  • нижняя треть значений → Q1
  • средняя треть → Q2
  • верхняя треть → Q3

Механизм вычисления

Процесс включает:

  1. сортировку входных данных
  2. разбиение массива на равные по размеру части
  3. определение пороговых значений (thresholds)

Формально:

  • если n — количество элементов, а k — число квантилей,
  • каждый квантиль содержит примерно n / k значений

Различие scaleQuantize и scaleQuantile

По принципу разбиения

  • scaleQuantize:

    • равные интервалы по значению
    • не учитывает распределение данных
  • scaleQuantile:

    • равные группы по количеству элементов
    • учитывает распределение данных

По устойчивости к выбросам

  • scaleQuantize чувствителен к выбросам, так как расширяет общий диапазон
  • scaleQuantile устойчив, так как работает с порядковыми позициями

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

Картограммы и тепловые карты

Для цветового кодирования плотности значений часто используется квантование:

const color = d3.scaleQuantile()
  .domain(dataset)
  .range(d3.schemeBlues[5]);

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


Использование с реальными данными

Пример набора данных

const data = [5, 7, 12, 18, 22, 29, 35, 42, 55, 60, 75, 90];

scaleQuantize на этом наборе

const q = d3.scaleQuantize()
  .domain([5, 90])
  .range(["A", "B", "C"]);

data.map(d => q(d));

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

scaleQuantile на том же наборе

const ql = d3.scaleQuantile()
  .domain(data)
  .range(["A", "B", "C"]);

data.map(d => ql(d));

Результат зависит от относительного положения элемента в отсортированном массиве.


Внутренняя логика thresholds в scaleQuantile

После инициализации шкала вычисляет пороговые значения:

scaleQuantile()
  .domain(data)
  .range(["low", "mid", "high"]);

console.log(scale.quantiles());

Метод quantiles() возвращает массив порогов, например:

[20, 45, 70]

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


Особенности поведения при изменении данных

scaleQuantize

  • при изменении домена интервалы пересчитываются линейно
  • структура остаётся стабильной

scaleQuantile

  • при изменении набора данных пересчитываются все пороги
  • даже небольшие изменения влияют на границы классов

Типичные сценарии выбора

Когда применяется scaleQuantize

  • равномерно распределённые данные
  • простая категоризация значений
  • визуальные шкалы с фиксированными диапазонами

Когда применяется scaleQuantile

  • статистические распределения
  • данные с выбросами
  • задачи равномерного распределения объектов по категориям

Влияние на визуальные метафоры

Квантование напрямую влияет на восприятие графиков:

  • scaleQuantize создаёт геометрически равные сегменты, но может искажать восприятие плотности
  • scaleQuantile сохраняет статистическую справедливость распределения, но искажает интервалы значений

Связь с другими шкалами D3

Квантовые шкалы занимают промежуточное положение между:

  • scaleLinear — непрерывная шкала
  • scaleThreshold — ручное задание границ
  • scaleQuantize / scaleQuantile — автоматическая дискретизация

scaleThreshold позволяет задать пороги вручную:

d3.scaleThreshold()
  .domain([10, 50, 100])
  .range(["A", "B", "C", "D"]);

Комбинирование с цветовыми схемами

Часто квантильные шкалы используются вместе с палитрами D3:

d3.scaleQuantile()
  .domain(data)
  .range(d3.schemeRdYlBu[5]);

Такой подход обеспечивает согласованное визуальное распределение цветовых классов.


Поведение при малом количестве данных

При малом числе элементов:

  • scaleQuantile может давать менее точные квантильные границы
  • scaleQuantize сохраняет предсказуемость, но теряет смысл статистической группировки

Влияние сортировки данных

  • scaleQuantize не зависит от порядка данных
  • scaleQuantile требует сортировки и полностью опирается на порядок значений

Принцип интерпретации выходных значений

Обе шкалы возвращают дискретные категории, но интерпретация различается:

  • в scaleQuantize категория — функция положения на числовой оси
  • в scaleQuantile категория — функция ранга в распределении