Функции масштаба: scale(), domain(), range()

Визуализация данных в Vega и Vega-Lite опирается на преобразование исходных значений в экранные координаты. Центральную роль в этом процессе выполняют шкалы (scales), которые задают отображение между доменом данных и диапазоном отображения.

Шкала формализуется как функция преобразования:

  • domain — пространство входных данных
  • range — пространство выходных значений (экран, цвет, размер и т.д.)

Функция scale() в Vega

В Vega выражениях scale() используется как функция доступа к зарегистрированной шкале. Она выполняет преобразование значения через заранее определённую конфигурацию масштаба.

Базовая форма:

scale("имя_шкалы", значение)

Пример:

scale("xscale", datum.value)

В этом случае:

  • "xscale" — идентификатор шкалы, определённой в секции scales
  • datum.value — входное значение
  • результат — числовая координата на оси X

Принцип работы scale()

Функция scale() не является математической функцией в чистом виде. Она представляет собой интерфейс к объекту масштабирования, который включает:

  • тип преобразования (linear, ordinal, band, time и др.)
  • domain (область входных значений)
  • range (область выходных значений)
  • дополнительные параметры (clamp, nice, padding и др.)

Внутри Vega выражение:

scale("x", 10)

эквивалентно вызову внутреннего преобразования:

xScale(10) → вычисленное значение диапазона

domain(): определение входного пространства

Domain задаёт множество значений, которые поступают на вход шкалы. В Vega и Vega-Lite domain может быть:

  • массивом фиксированных значений
  • вычисляемым диапазоном (min/max)
  • привязанным к данным (data-driven domain)

Числовой domain

{
  "domain": [0, 100]
}

Отображает значения от 0 до 100.

Автоматический domain

{
  "domain": {"data": "table", "field": "value"}
}

В этом случае границы вычисляются из набора данных.


Поведение domain в разных типах шкал

Линейные шкалы

Для linear:

  • domain интерпретируется как непрерывный интервал
  • применяется интерполяция

Категориальные шкалы

Для ordinal:

  • domain — список категорий
  • порядок элементов влияет на размещение
{
  "type": "ordinal",
  "domain": ["A", "B", "C"]
}

Временные шкалы

Для time:

  • domain задаётся датами
  • поддерживается интерполяция по времени

range(): определение выходного пространства

Range задаёт, во что преобразуются значения domain.

Типичные диапазоны:

  • пиксели (координаты)
  • цвета
  • размеры элементов
  • углы и радиусы

Числовой range (координаты)

{
  "range": [0, 500]
}

Значения domain отображаются в пиксельный диапазон.


Цветовой range

{
  "range": ["red", "blue"]
}

Используется для градиентных или категориальных цветовых шкал.


Дискретный range

{
  "range": [0, 10, 20, 30]
}

Каждому элементу domain сопоставляется фиксированное значение range.


Взаимосвязь domain и range

Математически шкала реализует отображение:

f: domain → range

Для линейной шкалы:

f(x) = rangeStart + (x - domainStart) * k

где:

k = (rangeEnd - rangeStart) / (domainEnd - domainStart)

genui{“math_block_widget_always_prefetch_v2”:{“content”:“f(x)=r_0 + (x-d_0)”}}


scale(), domain(), range() в Vega-Lite

В Vega-Lite шкалы задаются декларативно через encoding и scale.

Пример линейной шкалы:

{
  "mark": "point",
  "encoding": {
    "x": {
      "field": "value",
      "type": "quantitative",
      "scale": {
        "domain": [0, 100],
        "range": [0, 400]
      }
    }
  }
}

Автоматическое вычисление domain в Vega-Lite

Если domain не задан, Vega-Lite вычисляет его автоматически:

{
  "x": {
    "field": "value",
    "type": "quantitative"
  }
}

Поведение:

  • извлекается min/max из данных
  • добавляется padding при необходимости
  • применяется “nice rounding”

Band scale: domain и range для категорий

Band scale используется для дискретных категорий с шириной полос:

{
  "type": "band",
  "domain": ["A", "B", "C"],
  "range": [0, 300]
}

Особенности:

  • domain определяет порядок категорий
  • range делится на равные интервалы
  • добавляется padding между элементами

Time scale: работа с временными рядами

{
  "type": "time",
  "domain": ["2024-01-01", "2024-12-31"],
  "range": [0, 800]
}

Особенности:

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

Использование scale() в выражениях позиционирования

В Vega expressions scale() применяется не только к осям, но и к любым визуальным свойствам:

Позиция X

scale("x", datum.value)

Цвет

scale("color", datum.category)

Размер

scale("size", datum.metric)

Комбинирование шкал

Одна визуализация может содержать несколько шкал:

  • xscale — координата X
  • yscale — координата Y
  • colorScale — цветовая кодировка
  • sizeScale — размер маркеров

Каждая шкала имеет собственные domain и range.


Нелинейные шкалы и трансформации

domain и range сохраняются, но добавляется функция преобразования:

log scale

f(x) = log(x)

sqrt scale

f(x) = √x

power scale

f(x) = x^p

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


Поведение clamp и ограничение range

При включённом clamp: true значения вне domain ограничиваются краями range:

  • x < domain.min → range.min
  • x > domain.max → range.max

Это предотвращает выход графики за пределы области отображения.


Нормализация через domain и range

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

value_normalized = (value - domain_min) / (domain_max - domain_min)

x_{norm}=

После нормализации применяется range-масштабирование.


Дискретизация range в ordinal шкалах

Для категорий:

  • domain: набор меток
  • range: набор позиций или цветов

Отображение:

A → 0
B → 1
C → 2

или

A → red
B → green
C → blue

Padding и расширение domain

В Vega-Lite domain может автоматически расширяться:

  • для предотвращения обрезки точек
  • для визуального баланса графика

Пример:

{
  "scale": {
    "padding": 10
  }
}

Padding влияет на фактический диапазон range.


Итоговая модель взаимодействия

Шкала в Vega и Vega-Lite реализует трёхкомпонентную модель:

  • входные данные (domain)
  • функция преобразования (scale type)
  • выходное пространство (range)

Вызов scale() выполняет применение этой модели к конкретному значению, обеспечивая согласованное отображение данных в координатах, цветах и других визуальных свойствах.