Краткий обзор основ использования VegaLite.jl; одна из самых популярных библиотек статистических графиков Джулии

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

Julia — отличный язык программирования, особенно для науки. Он имеет многократную отправку, он быстрый и очень высокого уровня. Тем не менее, есть один регион, где у Джулии есть некоторые недостатки по сравнению с аналогичными вариантами, — это ее экосистема. На самом деле я много говорил об этом в другой статье, где обсуждал проблемы, с которыми сталкивается язык Julia и его соответствующая экосистема. Если вам интересно такое чтение, вы можете ознакомиться с этой статьей здесь:



Учитывая, что у Джулии довольно незрелая экосистема, значит ли это, что возможности визуализации данных в Джулии весьма ограничены? Первый ответ на этот вопрос — нет, но второй ответ — даже если бы он был ограничен — Джулия очень хорошо знакома с библиотеками компилятора LLVM и языком программирования C, а это значит, что чаще всего она могла бы вызывать внешний библиотека в любом случае, когда юлианский пакет не подходит для приложения.

Несмотря на то, что Джулия относительно незрелая, и это правда, что можно получить лучшую визуализацию и более надежный API, используя другой язык, все еще есть несколько потрясающих вариантов, полностью написанных на Джулии. Одним из примеров такой библиотеки является Vegalite.jl. Vegalite.jl — это модулированная библиотека визуализации для Джулии, которая, я бы сказал, наиболее похожа на Plot.ly… Что на самом деле не так уж и плохо —

Я люблю Plot.ly!

Еще одна вещь, о которой стоит упомянуть, это то, что у Джулии теперь также есть порт Plot.ly, так что вы всегда можете использовать Plot.ly. Кроме того, у них даже есть Plot.ly Dash для Джулии. Если вы хотите узнать больше о некоторых библиотеках, которые не являются Plot.ly или Vegalite.jl для языка Julia, то я настоятельно рекомендую эту статью, в которой я обсуждаю пакет Plots.jl, а также мой личный фаворит для Julia, Овод.jl:



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



Подробнее о VegaLite.jl

Первое, что я хотел бы обсудить о Vegalite, это то, насколько на самом деле инклюзивной является библиотека. Просто взглянув на домашнюю страницу документации, мы быстро узнаем, сколько всего включено в пакет Vegalite.jl. Этот пакет можно использовать для многих вещей, и это не ограничивается только графикой.

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

Первое, что следует сказать об этом методе, это то, что он, вероятно, превосходит большинство других пакетов, с которыми он может конкурировать. Этот JSON-способ ведения дел, безусловно, очень эффективен, по крайней мере, когда речь идет об обработке ЦП, однако у меня может быть проблема с моей памятью, если я часто использую этот пакет в своей работе. Еще я хотел бы добавить, что прекомпиляция была очень быстрой. Одна вещь, которую я ненавижу во многих модулях Julia, это то, что предварительная компиляция может занять тревожное количество времени, Plots.jl — отличный пример этого. Тем не менее, это довольно крутой метод, но в нем, безусловно, есть некоторые странности.

В мире визуализации данных принято использовать определенные подходы к такого рода сценариям. Например, код большинства языков для такой вещи будет примерно таким:

plt = plot(feature, other_feature, arguments)

Однако в Vegalite все становится немного странно. Макрос @vlplot используется практически для всего. Этот макрос возвращает тип, который мы рассмотрим, когда начнем рисовать, и этот тип также предназначен для работы с некоторыми довольно интересными вещами. Сила этого пакета действительно заключается во внутреннем конструкторе этого типа.

Базовый график

Теперь, когда у нас есть представление о Vegalite, давайте окунемся в него и построим кое-какой график!

import VegaLite: @vlplot

Как упоминалось ранее, в этом пакете действительно не так много того, что нам нужно будет импортировать. Имея это в виду, я буду поддерживать чистоту своей среды, напрямую импортируя макрос. Теперь давайте посмотрим на базовый пример точечной диаграммы. Данные, которые нам нужно предоставить для этого, будут типа Array(s). Мы предоставляем соответствующие массивы для аргументов ключевых слов. Vegalite также имеет множество наборов данных, которые можно использовать для загрузки некоторых данных, поэтому я сделаю это, а затем назначу данные новому массиву, который затем будет готов для включения в наш вызов макроса.

using VegaDatasets
data = dataset("cars")

Затем мы можем использовать правильный побитовый оператор, чтобы «вставить» эти данные в наш макрос и создать новый график:

data |> @vlplot(:point)

Поздравляем, вы только что создали свой первый график VegaLite! Ну, я не уверен, что мы должны называть это сюжетом, это больше похоже на пулю. VegaLite на самом деле отрисовывает все данные, которые мы предоставили макросу, единственная проблема в том, что у него нет ни максимума, ни минимума. Позвольте уточнить, всякий раз, когда выполняется графическая математика, нам нужно найти идеальный пиксель на экране, чтобы поместить заданную форму. Проблема в том, что разрешения и размеры экрана постоянно разные. При этом, если я помещу свое изображение высотой 30 пикселей на экран 1080p или на графику такого размера, оно не будет находиться в одном и том же месте, если мы перейдем на 240p.

Чтобы смягчить это, дробь рассчитывается путем деления значения на разрешение, чтобы получить процентное соотношение пикселя к целому. После этого произведение этого процента и разрешения или размера изображения вычитается из размера изображения, и тогда это наше окончательное местоположение пикселя. Откуда я так много об этом знаю? На самом деле я сделал свою собственную странную маленькую графическую библиотеку и некоторое время назад писал о ней статьи здесь, на Medium, вы можете просмотреть последнее обновление, которое я разместил в пакете, над которым я, возможно, скоро возьмусь за работу!



Чтобы заставить наш график VegaLite действительно работать, нам нужно будет добавить два новых аргумента ключевого слова к вызову нашего макроса. Это просто наши значения x и y.

data |> @vlplot(:point, x=:Miles_per_Gallon, y=:Horsepower)

Настройка наших графиков

Последнее, что я хотел сделать в этом кратком введении в удивительный пакет VegaLite.jl, — это просто рассказать о некоторых основных изменениях, которые можно было бы внести в их сюжет. Я не хотел слишком подробно рассказывать обо всем в Vegalite, потому что там просто слишком много, по крайней мере, для одной статьи, возможно, я вернусь к более подробному рассказу об этом пакете в будущем.

Во-первых, точечные графики — отличная вещь и замечательный инструмент, но они полезны не во всех ситуациях, поэтому давайте изменим тип графика, с которым мы работаем. Первый аргумент и единственный позиционный аргумент, точка символа — это то, что мы хотим заменить. Например, бар:

data |> @vlplot(:bar, x=:Miles_per_Gallon, y=:Horsepower)

Мы можем предоставить здесь все виды ключевых слов, но назовем некоторые из них:

  • параметры
  • ширина
  • непрозрачность
  • трансформировать

Их много, поэтому мы просто сосредоточимся на основах, добавив немного бликов. Давайте теперь создадим некоторые новые данные для работы:

arm_motion_data = [(; ϕ1 = cos(t), ϕ2 = sin(t), t) for t in 0:0.01:2pi]

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

arm_motion_data |>
VegaLite.@vlplot(
    width = 500,
    height = 500,
    transform = [
        {calculate = "cos(datum.ϕ1)", as = "px1"},
        {calculate = "sin(datum.ϕ1)", as = "py1"},
        {calculate = "datum.px1 + cos(datum.ϕ2)", as = "px2"},
        {calculate = "datum.py1 + sin(datum.ϕ2)", as = "py2"},
    ],
)

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

+
VegaLite.@vlplot(
    mark = :rule,
    x = {datum = 0, scale = {domain = [0, 2.8]}},
    y = {datum = 0, scale = {domain = [-1.4, 1.4]}},
    x2 = "px1:q",
    y2 = "py1:q"
) +
VegaLite.@vlplot(mark = :point, x = "px1:q", y = "py1:q") +
VegaLite.@vlplot(mark = :rule, x = "px1:q", y = "py1:q", x2 = "px2:q", y2 = "py2:q") +
VegaLite.@vlplot(mark = :point, x = "px2:q", y = "py2:q")

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

arm_motion_data = [(; ϕ1 = cos(t), ϕ2 = sin(t), t) for t in 0:0.01:2pi]
arm_motion_data |>
VegaLite.@vlplot(
    width = 500,
    height = 500,
    transform = [
        {calculate = "cos(datum.ϕ1)", as = "px1"},
        {calculate = "sin(datum.ϕ1)", as = "py1"},
        {calculate = "datum.px1 + cos(datum.ϕ2)", as = "px2"},
        {calculate = "datum.py1 + sin(datum.ϕ2)", as = "py2"},
    ],
) +
VegaLite.@vlplot(
    mark = :rule,
    x = {datum = 0, scale = {domain = [0, 2.8]}},
    y = {datum = 0, scale = {domain = [-1.4, 1.4]}},
    x2 = "px1:q",
    y2 = "py1:q"
) +
VegaLite.@vlplot(mark = :point, x = "px1:q", y = "py1:q") +
VegaLite.@vlplot(mark = :rule, x = "px1:q", y = "py1:q", x2 = "px2:q", y2 = "py2:q") +
VegaLite.@vlplot(mark = :point, x = "px2:q", y = "py2:q")

Заключение

Если вы используете язык программирования Julia или даже просто интересуетесь им, я настоятельно рекомендую проверить пакет Vegalite. В пакете есть множество замечательных функций и действительно крутая и интересная методология, которую я раньше не видел. Большое спасибо за чтение, и я надеюсь, что этот аккуратный небольшой пакет и статья вызвали у вас максимальный интерес, когда дело доходит до визуализации данных в Джулии!