line

Vega представляет декларативную грамматику визуализации, в которой линейные графики описываются через структуру данных, масштабирование и правила отрисовки, а не через императивное рисование на canvas или SVG. В этой модели линия рассматривается как набор упорядоченных точек, соединённых в соответствии с заданной семантикой оси X.

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


Базовая структура линейного графика

Линейный график в Vega/Vega-Lite строится вокруг трёх ключевых компонентов:

  • данные (data)
  • кодирование (encoding)
  • геометрический примитив (mark: line)

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


Минимальная спецификация линии в Vega-Lite

Линейный график чаще всего начинается с такой структуры:

{
  "data": {
    "values": [
      {"x": 1, "y": 10},
      {"x": 2, "y": 25},
      {"x": 3, "y": 18}
    ]
  },
  "mark": "line",
  "encoding": {
    "x": {"field": "x", "type": "quantitative"},
    "y": {"field": "y", "type": "quantitative"}
  }
}

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

  • mark: "line" задаёт тип геометрии
  • x определяет порядок соединения точек
  • y задаёт значение функции

Роль сортировки данных

Линия в Vega/Vega-Lite чувствительна к порядку точек. При отсутствии явного указания сортировки возможны искажения формы графика.

Корректное управление порядком:

"encoding": {
  "x": {
    "field": "x",
    "type": "quantitative",
    "sort": "ascending"
  }
}

Сортировка особенно критична при:

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

Линии временных рядов

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

{
  "data": {
    "values": [
      {"date": "2024-01-01", "value": 30},
      {"date": "2024-01-02", "value": 45},
      {"date": "2024-01-03", "value": 40}
    ]
  },
  "mark": "line",
  "encoding": {
    "x": {"field": "date", "type": "temporal"},
    "y": {"field": "value", "type": "quantitative"}
  }
}

Тип temporal активирует:

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

Интерполяция линий

В Vega доступна настройка формы соединения точек через interpolate.

Основные варианты:

  • linear — прямые отрезки
  • monotone — сглаживание без пересечений
  • basis — B-сплайновая кривая
  • step — ступенчатая функция

Пример:

{
  "mark": {
    "type": "line",
    "interpolate": "monotone"
  }
}

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


Множественные линии (series)

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

{
  "mark": "line",
  "encoding": {
    "x": {"field": "x", "type": "quantitative"},
    "y": {"field": "y", "type": "quantitative"},
    "color": {"field": "category", "type": "nominal"}
  }
}

Поле color автоматически:

  • разделяет данные на серии
  • создаёт легенду
  • строит независимые линии

Каждая категория становится отдельной линией в одном пространстве координат.


Контроль разрыва линии (null values)

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

В Vega-Lite:

"mark": {
  "type": "line",
  "strokeDash": [5, 5]
}

Но поведение по пропускам задаётся через null обработку:

  • null → разрыв линии
  • фильтрация → непрерывная линия
  • трансформация → заполнение значений

Линии и трансформации данных

Vega/Vega-Lite поддерживает встроенные трансформации перед отрисовкой:

Агрегация

"transform": [
  {
    "aggregate": [{"op": "mean", "field": "value", "as": "avg"}],
    "groupby": ["date"]
  }
]

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


Фильтрация

"transform": [
  {"filter": "datum.value > 0"}
]

Фильтрация часто используется для устранения шумов или некорректных значений.


Масштабирование осей (scales)

Линия полностью зависит от шкал координат.

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

Используется по умолчанию для числовых данных:

  • равномерные интервалы
  • прямое отображение значений

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

"x": {"type": "quantitative", "scale": {"type": "log"}}

Применяется при:

  • экспоненциальном росте
  • финансовых графиках
  • научных измерениях

Настройка осей (axes)

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

"axis": {
  "title": "Время",
  "grid": true,
  "labelAngle": -45
}

Ключевые элементы:

  • заголовки
  • сетка
  • поворот подписей
  • форматирование чисел

Поведение линии при больших наборах данных

При тысячах точек возникают проблемы:

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

Решения:

  • агрегация
  • прореживание данных (sampling)
  • использование impute
  • серверная предобработка

Импутация пропусков

Vega позволяет восстанавливать недостающие значения:

"transform": [
  {
    "impute": "value",
    "key": "x",
    "method": "value",
    "value": 0
  }
]

Импутация влияет на непрерывность линии и может искажать реальные данные, если используется некорректно.


Комбинирование линий с другими mark

Линия часто комбинируется с точками:

"layer": [
  {
    "mark": "line"
  },
  {
    "mark": "point"
  }
]

Это усиливает читаемость:

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

Группировка через facet

Для разделения линий по панелям используется facet:

{
  "facet": {"field": "category", "type": "nominal"},
  "spec": {
    "mark": "line",
    "encoding": {
      "x": {"field": "x", "type": "quantitative"},
      "y": {"field": "y", "type": "quantitative"}
    }
  }
}

Каждая категория получает отдельный график.


Линии с накоплением логики (не stacked line)

В отличие от area chart, линейные графики:

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

Попытка имитировать stacking требует предварительной трансформации данных через cumulative sum.


Управление стилем линии

Vega предоставляет контроль над визуальными параметрами:

  • stroke — цвет линии
  • strokeWidth — толщина
  • strokeDash — пунктир
  • opacity — прозрачность

Пример:

"mark": {
  "type": "line",
  "strokeWidth": 2,
  "strokeDash": [2, 2]
}

Поведение при категориальной оси X

Если X категориальный:

  • линия соединяет категории в порядке сортировки
  • возможны визуальные артефакты при неправильном порядке

Поэтому критично задавать:

"sort": ["category"]

Производительность рендеринга

Основные факторы влияния:

  • количество точек
  • сложность интерполяции
  • количество слоёв
  • наличие анимаций

Оптимизация:

  • предварительная агрегация
  • ограничение количества элементов
  • упрощение геометрии

Итоговая модель линии в Vega/Vega-Lite

Линия концептуально представляет собой:

  • упорядоченный набор точек
  • функцию отображения X → Y
  • визуальную интерполяцию между значениями
  • результат декларативных трансформаций данных

Вся логика формируется комбинацией:

  • данных
  • масштаба
  • кодирования
  • маркера line