Канал facet

Facet представляет собой механизм построения малых кратных (small multiples), при котором одна и та же визуализация автоматически тиражируется по подмножествам данных. В терминах Vega-Lite facet реализует декларативное разбиение набора данных на группы с последующим построением отдельного графика для каждой группы в сетке строк и/или столбцов.

В отличие от агрегированных диаграмм, где сравнение происходит внутри одного полотна, facet переносит сравнение в пространство одинаковых визуализаций. Это радикально меняет структуру восприятия: вместо усложнения одной диаграммы происходит стандартизация множества экземпляров.

Facet опирается на операцию группировки. Исходный набор данных разбивается по значению одного или нескольких полей. Каждая уникальная комбинация значений формирует отдельную панель.

Формально:

  • имеется множество записей D
  • выбирается ключ группировки k(x)
  • формируются подмножества D₁, D₂, …, Dₙ, где каждый Dᵢ соответствует фиксированному значению ключа

Каждое подмножество отображается одной и той же спецификацией визуализации.

Facet как канал компоновки

В Vega-Lite facet является не только операцией над данными, но и каналом компоновки. Он определяет структуру сетки визуализации:

  • row — разбиение по строкам
  • column — разбиение по столбцам

Каждый канал задаёт независимое измерение раскладки. Комбинация row и column формирует двумерную матрицу панелей.

Простейшая форма декларации:

{
  "data": {"url": "data.csv"},
  "facet": {
    "row": {"field": "category", "type": "nominal"}
  },
  "spec": {
    "mark": "bar",
    "encoding": {
      "x": {"field": "value", "type": "quantitative"},
      "y": {"aggregate": "sum", "field": "amount"}
    }
  }
}

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

Row и column как независимые оси фасетирования

Использование row и column создаёт двумерную декомпозицию пространства данных.

Если заданы оба канала:

"facet": {
  "row": {"field": "region", "type": "nominal"},
  "column": {"field": "year", "type": "ordinal"}
}

формируется матрица:

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

Такой подход превращает визуализацию в таблицу графиков, где каждая ячейка — это независимая проекция данных.

Отличие facet от повторения (repeat)

Facet часто сравнивают с механизмом repeat, однако семантика различается.

Facet:

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

Repeat:

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

Таким образом, facet — это data-driven разбиение, а repeat — schema-driven дублирование.

Внутренняя структура facet в Vega-Lite

При компиляции спецификации Vega-Lite преобразует facet в низкоуровневую структуру Vega. На этом этапе происходит:

  1. группировка данных по ключам facet
  2. генерация подграфиков (sub-views)
  3. вычисление layout-сетки
  4. распределение шкал и доменов

Каждая facet-панель может иметь:

  • собственные шкалы (independent scales)
  • или общие шкалы (shared scales)
  • собственные оси или скрытые оси для оптимизации пространства

Выбор режима масштабов критически влияет на интерпретацию данных. Общие шкалы обеспечивают сравнимость, независимые — детализацию локальных закономерностей.

Заголовки панелей (facet headers)

Facet автоматически генерирует заголовки, связанные с группирующим полем. Эти заголовки выполняют роль метаданных панели.

Пример:

"facet": {
  "column": {
    "field": "product",
    "type": "nominal",
    "header": {"title": "Продукт"}
  }
}

Заголовки могут быть:

  • текстовыми
  • ориентированными (orientation: top, bottom, left, right)
  • форматированными через labelExpr
  • отключёнными полностью

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

Вложенные faceting-структуры

Facet может быть вложенным, создавая иерархические разбиения.

Пример:

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

Это создаёт двухуровневую структуру панелей, где каждая ячейка представляет пересечение категорий.

{
  "facet": {
    "row": {"field": "region", "type": "nominal"}
  },
  "spec": {
    "facet": {
      "column": {"field": "product_type", "type": "nominal"}
    },
    "spec": {
      "mark": "line",
      "encoding": {
        "x": {"field": "date", "type": "temporal"},
        "y": {"field": "value", "type": "quantitative"}
      }
    }
  }
}

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

Facet и агрегированные шкалы

Особое значение имеет взаимодействие facet с агрегированными полями.

При использовании агрегации внутри spec:

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

Пример:

"encoding": {
  "y": {"aggregate": "mean", "field": "score", "type": "quantitative"}
}

Здесь среднее значение считается отдельно для каждой facet-группы, что позволяет сравнивать распределения между подмножествами.

Производительность и оптимизация

Facet увеличивает нагрузку на рендеринг пропорционально числу групп. Основные факторы:

  • количество уникальных значений ключа
  • сложность spec
  • наличие независимых шкал
  • глубина вложенности

Оптимизационные стратегии:

  • ограничение cardinality (кардинальности) группирующего поля
  • предварительная агрегация данных
  • использование общих шкал вместо независимых
  • уменьшение числа визуальных элементов внутри панели

Facet в контексте декларативной визуализации

Facet демонстрирует ключевой принцип Vega-Lite: отделение данных, логики группировки и визуального представления.

Вместо ручного создания сетки графиков разработчик описывает:

  • правило разбиения
  • шаблон визуализации
  • структуру компоновки

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

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

Это делает facet не просто функцией, а базовым конструктивным оператором декларативной графической грамматики.

Связь facet с аналитическими паттернами

Facet часто используется для:

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

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

Ограничения модели фасетирования

Несмотря на выразительность, facet имеет ограничения:

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

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

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