Концепция шкалы в Vega-Lite

Шкала (scale) в Vega-Lite определяет способ преобразования исходных данных в визуальные значения. Именно шкалы отвечают за то, как числовые значения превращаются в координаты, размеры, цвета, прозрачность, толщину линий и другие визуальные параметры.

Внутри декларативной модели Vega-Lite шкала располагается между данными и визуальным представлением:

Данные → Шкала → Канал кодирования → Визуальный элемент

Например:

  • число 150 может быть преобразовано в координату x = 430;
  • категория "A" может быть преобразована в цвет #1f77b4;
  • значение 0.8 может стать прозрачностью opacity = 0.8.

Без шкалы Vega-Lite не знает, каким образом интерпретировать данные внутри графика.


Автоматическое создание шкал

В большинстве случаев Vega-Lite создаёт шкалы автоматически на основе:

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

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

{
  "data": {
    "values": [
      {"x": 10, "y": 20},
      {"x": 30, "y": 40},
      {"x": 50, "y": 60}
    ]
  },
  "mark": "point",
  "encoding": {
    "x": {"field": "x", "type": "quantitative"},
    "y": {"field": "y", "type": "quantitative"}
  }
}

Здесь Vega-Lite автоматически:

  1. анализирует диапазон x;
  2. анализирует диапазон y;
  3. строит линейные шкалы;
  4. распределяет значения по ширине и высоте графика.

Связь шкалы и каналов кодирования

Шкалы применяются к следующим каналам:

Канал Назначение
x горизонтальная координата
y вертикальная координата
color цвет
size размер
opacity прозрачность
shape форма
strokeWidth толщина линии
angle угол
fill заливка

Каждый канал может содержать собственную настройку scale.

Пример:

{
  "encoding": {
    "x": {
      "field": "price",
      "type": "quantitative",
      "scale": {
        "domain": [0, 1000]
      }
    }
  }
}

Компоненты шкалы

Шкала состоит из двух основных частей:

Компонент Назначение
domain входной диапазон данных
range выходной визуальный диапазон

Domain — область входных значений

domain определяет множество значений из данных.

Например:

"scale": {
  "domain": [0, 100]
}

Это означает:

Минимальное значение = 0
Максимальное значение = 100

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

По умолчанию Vega-Lite вычисляет domain автоматически.

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

Если данные содержат значения:

12, 35, 78, 91

то domain станет:

[12, 91]

Явное указание domain

Фиксированный domain используется для:

  • синхронизации нескольких графиков;
  • предотвращения «скачков» масштаба;
  • контроля интерпретации данных;
  • корректного сравнения.

Пример:

{
  "encoding": {
    "y": {
      "field": "temperature",
      "type": "quantitative",
      "scale": {
        "domain": [-50, 50]
      }
    }
  }
}

Domain для категориальных данных

Категориальные шкалы используют массив категорий.

{
  "scale": {
    "domain": ["A", "B", "C", "D"]
  }
}

Это позволяет:

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

Range — визуальный диапазон

range определяет, как значения отображаются визуально.

Например:

"scale": {
  "range": [0, 500]
}

означает:

Минимальное значение → 0 px
Максимальное значение → 500 px

Range для цветовых шкал

В цветовых шкалах range обычно задаёт палитру.

{
  "encoding": {
    "color": {
      "field": "profit",
      "type": "quantitative",
      "scale": {
        "range": ["red", "white", "green"]
      }
    }
  }
}

Типы шкал

Vega-Lite поддерживает множество типов шкал.

Тип Назначение
linear линейная шкала
log логарифмическая
pow степенная
sqrt квадратный корень
symlog симметрическая логарифмическая
time временная
utc время UTC
band полосовая
point точечная
ordinal порядковая

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

Наиболее распространённый тип.

{
  "scale": {
    "type": "linear"
  }
}

Линейная шкала сохраняет пропорции:

10 → 100 px
20 → 200 px
30 → 300 px

Используется для:

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

Логарифмическая шкала

Применяется для данных с огромным разбросом значений.

{
  "scale": {
    "type": "log"
  }
}

Пример данных:

1
10
100
1000
10000

Без логарифмической шкалы малые значения будут практически незаметны.


Особенности log-шкал

Логарифмические шкалы:

  • не поддерживают ноль;
  • не работают с отрицательными числами;
  • требуют положительных значений.

Неверно:

0
-10
15

Корректно:

1
10
100

Настройка основания логарифма

{
  "scale": {
    "type": "log",
    "base": 10
  }
}

Основание может быть:

  • 10;
  • 2;
  • Math.E.

Степенная шкала

{
  "scale": {
    "type": "pow",
    "exponent": 2
  }
}

Используется при нелинейном распределении данных.


Шкала квадратного корня

{
  "scale": {
    "type": "sqrt"
  }
}

Часто применяется для:

  • площадей кругов;
  • bubble charts;
  • размеров объектов.

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

Для временных данных Vega-Lite автоматически использует time.

{
  "encoding": {
    "x": {
      "field": "date",
      "type": "temporal"
    }
  }
}

UTC-шкалы

{
  "scale": {
    "type": "utc"
  }
}

Используются при:

  • международных системах;
  • серверных временных метках;
  • работе с часовыми поясами.

Ordinal-шкалы

Порядковые шкалы сопоставляют категории визуальным значениям.

{
  "scale": {
    "type": "ordinal"
  }
}

Пример:

"A" → красный
"B" → синий
"C" → зелёный

Band-шкалы

Используются для столбчатых диаграмм.

{
  "scale": {
    "type": "band"
  }
}

Band-шкала:

  • делит пространство на полосы;
  • вычисляет ширину столбцов;
  • поддерживает отступы.

Point-шкалы

Похожи на band-шкалы, но не выделяют ширину полосы.

{
  "scale": {
    "type": "point"
  }
}

Часто используются в:

  • line charts;
  • point charts;
  • categorical scatter plots.

Padding в band-шкалах

Внутренний отступ

{
  "scale": {
    "paddingInner": 0.1
  }
}

Внешний отступ

{
  "scale": {
    "paddingOuter": 0.05
  }
}

Zero

Параметр zero определяет, должен ли domain включать ноль.

{
  "scale": {
    "zero": true
  }
}

Особенно важно для:

  • bar chart;
  • area chart;
  • сравнительных диаграмм.

Почему zero важен

Неверный масштаб может визуально искажать данные.

Например:

95
96
97
98
99

Если ось начинается с 95, различия будут выглядеть огромными.

Если с 0 — различия будут интерпретироваться корректнее.


Nice

Параметр nice округляет domain до «красивых» значений.

{
  "scale": {
    "nice": true
  }
}

Например:

Исходный domain:
[3, 97]

После nice:
[0, 100]

Clamp

clamp ограничивает значения внутри диапазона.

{
  "scale": {
    "clamp": true
  }
}

Если значение выходит за пределы domain, оно будет «прижато» к границе.


Reverse

Инвертирует направление шкалы.

{
  "scale": {
    "reverse": true
  }
}

Полезно для:

  • рейтингов;
  • heatmap;
  • специальных визуализаций.

Color scales

Цветовые шкалы — одна из важнейших частей Vega-Lite.

Непрерывная шкала

{
  "encoding": {
    "color": {
      "field": "temperature",
      "type": "quantitative"
    }
  }
}

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

{
  "encoding": {
    "color": {
      "field": "category",
      "type": "nominal"
    }
  }
}

Цветовые схемы

Vega-Lite поддерживает встроенные схемы.

{
  "scale": {
    "scheme": "viridis"
  }
}

Популярные схемы:

Схема Тип
viridis последовательная
magma последовательная
plasma последовательная
inferno последовательная
blues монохромная
tableau10 категориальная
category10 категориальная

Diverging scales

Дивергентные шкалы используются при наличии центральной точки.

Например:

убыток ← 0 → прибыль

Пример:

{
  "scale": {
    "domain": [-100, 0, 100],
    "range": ["red", "white", "green"]
  }
}

Interpolate

Управляет интерполяцией цветов.

{
  "scale": {
    "interpolate": "lab"
  }
}

Варианты:

  • rgb;
  • lab;
  • hcl;
  • hsl.

Size scales

Размер также управляется шкалой.

{
  "encoding": {
    "size": {
      "field": "population",
      "type": "quantitative"
    }
  }
}

Настройка диапазона размеров

{
  "scale": {
    "range": [10, 1000]
  }
}

Opacity scales

{
  "encoding": {
    "opacity": {
      "field": "density",
      "type": "quantitative"
    }
  }
}

Полезно при:

  • overplotting;
  • heat visualization;
  • density maps.

Отключение шкалы

Иногда шкалу необходимо отключить.

{
  "scale": null
}

Пример:

{
  "encoding": {
    "color": {
      "value": "red",
      "scale": null
    }
  }
}

Независимые шкалы

В составных визуализациях шкалы могут быть независимыми.

{
  "resolve": {
    "scale": {
      "y": "independent"
    }
  }
}

Это особенно важно при:

  • faceting;
  • layered charts;
  • concatenation.

Общие шкалы

По умолчанию Vega-Lite пытается объединять шкалы.

{
  "resolve": {
    "scale": {
      "color": "shared"
    }
  }
}

Scale и легенды

Легенды автоматически строятся на основе шкал.

Данные → Шкала → Легенда

Изменение шкалы автоматически изменяет:

  • цвета;
  • подписи;
  • диапазоны;
  • деления.

Scale и оси

Оси также напрямую связаны со шкалами.

Scale → Axis

Поэтому параметры:

  • domain;
  • nice;
  • reverse;
  • type;

влияют и на отображение осей.


Discrete и continuous scales

Непрерывные шкалы

Используются для:

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

Примеры:

  • linear;
  • log;
  • sqrt;
  • time.

Дискретные шкалы

Используются для:

  • категорий;
  • групп;
  • текстовых значений.

Примеры:

  • ordinal;
  • band;
  • point.

Влияние типа данных на выбор шкалы

Vega-Lite автоматически выбирает шкалу на основе type.

Тип данных Шкала
quantitative linear
temporal time
nominal ordinal
ordinal point / band

Scale bins

При биннинге шкалы работают особым образом.

{
  "x": {
    "field": "value",
    "bin": true
  }
}

Vega-Lite:

  1. создаёт интервалы;
  2. строит дискретную шкалу;
  3. отображает диапазоны.

DomainMin и DomainMax

Позволяют частично контролировать domain.

{
  "scale": {
    "domainMin": 0,
    "domainMax": 100
  }
}

DomainMid

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

{
  "scale": {
    "domainMid": 0
  }
}

Round

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

{
  "scale": {
    "round": true
  }
}

Это уменьшает размытие линий.


Padding

Общий padding:

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

Особенно полезен для:

  • точечных диаграмм;
  • line charts;
  • категориальных осей.

Align

Управляет распределением band-элементов.

{
  "scale": {
    "align": 0.5
  }
}

Эксплицитные и неявные шкалы

Неявные

Создаются автоматически:

{
  "x": {
    "field": "value"
  }
}

Эксплицитные

Настраиваются вручную:

{
  "x": {
    "field": "value",
    "scale": {
      "type": "log",
      "domain": [1, 1000]
    }
  }
}

Практические рекомендации

Для bar charts

  • использовать zero: true;
  • избегать логарифмических шкал;
  • контролировать band-padding.

Для scatter plots

  • использовать linear-шкалы;
  • добавлять padding;
  • контролировать domain.

Для heatmaps

  • тщательно подбирать color-scale;
  • использовать perceptual palettes;
  • избегать слишком насыщенных цветов.

Для временных рядов

  • применять time/utc;
  • фиксировать domain при сравнении;
  • учитывать timezone.

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

Неверный тип шкалы

{
  "type": "nominal"
}

для числовых данных приводит к дискретизации.


Использование log с нулём

0
10
100

создаёт некорректную визуализацию.


Слишком узкий domain

{
  "domain": [95, 100]
}

может искусственно преувеличивать различия.


Неподходящая цветовая схема

Радужные палитры:

  • ухудшают восприятие;
  • создают ложные границы;
  • затрудняют анализ.

Архитектурная роль шкал

В Vega-Lite шкалы являются фундаментальным уровнем абстракции между:

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

Именно шкалы превращают набор абстрактных значений в полноценную визуальную структуру, обеспечивая:

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