Методика борьбы!

"Первая часть"

"Часть вторая"

"Часть третья"

"Ноутбук"

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

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

В отличие от:

Но после того, как я закончил экспорт, мне пришла в голову мысль. Очевидно, мы можем построить X и Y, но как насчет сравнения данных? В конце концов, большую часть времени вы хотите построить диаграмму разброса некоторых данных, вы сравниваете более одного X, а не просто визуализируете положение одного X. Чтобы изменить это, я планирую использовать DataFrames, поскольку Lathe уже добавлен как зависимость в Project.toml; а Lathe имеет DataFrames.jl в качестве зависимости, а это означает, что любой, кто использует Hone, скорее всего, уже имеет DataFrames на своем компьютере.

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

Я шучу…

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

Это не такая уж большая проблема и напоминает мне программирование событий основного цикла, где вам постоянно нужно проверять состояние флагов, чтобы выполнить что-либо, в противном случае он будет выполняться на каждом тике процессора, что довольно забавно. . К счастью, поскольку мы программируем на Julia, мы можем быть лучше этого. Мы можем сделать это, используя множественную отправку Джулии, и мы можем начать с написания двух функций, которые должны обрабатывать два разных типа.

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

И теперь, когда мы вызываем это с нашими двумя типами:

Функции выполняются соответственно для каждого типа.

Мы можем применить эту идею в Hone, создав новую функцию Scatter, которая будет обрабатывать Data-Frame, а не массивы. Я переименовал нашу старую функцию Scatter в _arrayscatter, а нашей новой будет _dfscatter. Я использую эту схему именования с подчеркиванием из личных предпочтений, потому что это помогает мне различать функции конечного пользователя и внутренние функции, которые пользователь никогда не увидит, хотя в этом нет необходимости, я действительно думаю, что важно оставаться последовательным .

А теперь просто добавляем нашу диспетчерскую строку:

Обратите внимание, что мне пришлось сначала загрузить DataFrames.jl в сеанс, чтобы использовать тип DataFrame. Также следует отметить, что y имеет утверждение типа Symbol, а не Array, как вы могли ожидать, это потому, что мы предполагаем, что массив, который мы хотели бы использовать в качестве нашего Y, находится внутри кадра данных, поэтому мы можно назвать это так:

x[y]

довольно странно.

Теперь мы можем построить фрейм данных, чтобы продемонстрировать, что все действительно работает:

df = DataFrame(:one => [1,5,2,3], :two => [8,4,5,3], :y => [5,6,2,3])

И когда мы передаем его через нашу функцию:

Итак, диспетчеризация работает, но нам все еще нужно добавить логику к построению графика для функции фрейма данных. Для этого я сначала возьму код из обычной функции разброса, а затем просто продублирую синтаксический анализатор координат, чтобы он анализировал оба X по отдельности. Результатом, который мы ищем, должно быть четыре дополнительных точки на диаграмме рассеяния, всего восемь. Итак, сначала я покажу вам результат, а затем углублюсь в рефакторинг, который мне пришлось провести:

Для объяснения я буду идти строка за строкой, потому что здесь много всего. Во-первых, в функции рассеяния, где получены максимумы и минимумы; Мне пришлось переместить вычисление максимума X в итерационный цикл, потому что на этот раз мы перебирали разные массивы с разными максимумами. Однако я сохранил исходное положение Y:

function _dfscatter(x,y,shape,debug=false)
    topy = maximum(x[y])

Затем цикл, который необходимо переместить, изменяет все координаты на проценты в исходной функции в цикл (как и должно быть).

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

так что давайте это изменим.

Первым шагом в этом процессе будет сделать наш параметр «shape» массивом в утверждении типа нашей полиморфной отправки, например:

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

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

Добавляем новую форму.

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

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

круг.

Возьми? В любом случае, мы можем использовать формы, а не цвет, чтобы отличать два столбца друг от друга.

Посмотрите на светлую сторону, по крайней мере, это не много текста или чего-то подобного.

Теперь давайте пропустим эти формы через нашу функцию _dfscatter!

Я позволю Губке Бобу объяснить, каково это:

Вывод

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

Что касается построения фрейма данных, конечно, есть еще несколько вещей, которые нужно сделать, и есть еще несколько вещей, которые нужно сделать в целом. Я чувствую, что мы очень близки к тому, чтобы Hone стал довольно приличной библиотекой для построения графиков, несмотря ни на что! Если вы хотите попробовать Hone, вот он на Github:



Спасибо за чтение!