Чи залежать результати виборів у Києві від розміщення гілок метрополітену – експеримент з бібліотекою d3.js

У стрічці новин я помітив матеріал, де результати волевиявлення співвітчизників у першому турі президентських виборів було нанесено на карту . Мені здалося, що результати голосування по Києву мають певну геопозиційну закономірність, а саме перевага одного кандидата на дільницях вздовж гілок метро. А оскільки я давно хотів розібратися з бібліотекою d3.js та не було завдань, де її можна використати, вирішив зробити статистичне дослідження (побудувати декілька графіків), щоб підтвердити чи спростувати цю закономірність.

Збір інформації

Коли почав збирати інформацію, відкриті дані з результатами голосування не були доступні на сайті ЦВК , оскільки ще тривав підрахунок голосів. Тож була ідея написати краулер для отримання результатів з публічних сторінок. Альо обрав більш легкий варіант — запозив вже підготовлені дані з сайту dekoder.org . Крім результатів голосування на dekoder.org також запозичив координати виборчий дільниць. Координати розміщення станцій метро взявши з Вікіпедії, межі Києва — з nominatim.openstreetmap.org .

Підготовка даних

Вибірка з результатами голосування була обмежена Києвом. Для простоти та наочності з усіх кандидатів узяв тільки три лідери, а їхні імена замінив на Green, Red і Yellow, щоб їх оминули пошукові системи (і щоб ухилитися від написання легенди до графіків).

До результатів голосування на дільницях виборчий додав колонку «відстань до найблищої станції метро». Розрахунок відстані зробив за формулою «сферичної проекції землі на площину». Скрипт підготовки даних: /build/index.js .

Підводні камені

Збір проекту

Для збору проекту вирішив використати такі популярні технології: [email protected] + [email protected]. Узяв базовий «пустий» конфіг.

Babel також вимагає @babel/polyfill для реалізації можливостей, недоступних лише трансформацією синтаксису. Як виявилося в подальшому, пакет @babel/polyfill не включає Fetch API через те, що вона не описана в ECMAScript — стандартах, тож я додав ще один поліфіл.

У якийсь момент розробки я зрозумів, що проект не працює в IE. Я почав більш детально смотреть на конфігурацію збірки webpack-а, а потім і babel, і наче все було вірно, тому я вирішив копати з боку зібраних файлів. Як виявилось, не траслітерувалися залежності з node_modules. Після подальшого пошуку я виявивши, що проспав реліз 7 версії Babel, де був введений додатковий файл конфігурації 'babel.config.js' для npm пакетів.

d3js

Кількість реалізованих прикладів використання бібліотеки дозволяє взагалі не відкривати документацію, якщо ви на базовому рівні знайомі з SVG, звичайно. За годину написання переглянув такі офіційні ресурси з прикладами: bl.ocks.org , github.com/d3/d3/wiki/Gallery , d3js.org . Альо для побудови динамічних графіків (і не тільки) все ж варто розібратися, як працює концепція 'enter/update/exit' (Data joins and selections). Вісь статті, які допомогли розібратися з цим питанням: «Enter, Update, Exit» , «Введення в d3.js» (російськомовна, та доволі якісна).

Проблему ресайзу графіків добре вирішено в туторіалі . Ця техніка буде працювати для будь-якого svg-зображення. Загалом було зроблено 21 коміт, ~800 строчок власного коду, js бандл на 556 кб.

Результати дослідження

scatter plot — де кожна точка має координати — результат у відсотках для обраних кандидатів на дільниці та віддаленість дільниці від станції метро. Інформація дає загальні уявлення, але хочеться більше структурувати дані.

line chart — об'єднання результатів дільниць за віддаленістю в групи із заданим кроком, крок задається слайдером. Також додав графік з кількістю голосів у об'єднання об'єднаних групах. На графіку можна побачити що, присутні тенденції спадання у кандидата Red та зростання Green та Yellow (меншою мірою) залежно від віддаленості від станцій метро. Також через малу кількість віддалених дільниць у кінці графіка помітні стрибки.

line chart, stacked bar chart — цього разу крок розподілений таким чином, щоб кількість голосів в групах наближалась до рівномірного розподілу, тобто розділення на групи дільниць з однаковою кількістю голосів. Слайдер задає кількість груп. Графік більш плавний, подолана проблема малої насиченості в групах, але результати повторють попередні висновки.

Припустивши, що залежність результатів лінійна, також розрахував коефіцієнт кореляції Пірсона (величини представлені в першому графіку). Інтерпретація значень дозволяє зробити висновок, що кореляція присутня для всіх кандидатів, хоч і має низький рівень. Лише загальна близькість двох кандидатів дозволяє виявити її пробачимо переглядом картин.

Насамкінець хочу поділитися думкою, що зазвичай візуалізація кластеризації на карті представлена колами, але чому б не використовувати діаграму Вороного ?


Слайдер змінює к — параметр k-means кластеризації, re-call — повторює цикл кластеризації. Оскільки k-means не гарантує глобального екстремуму, шкірного разу можливий інший результат (залежить від початкових точок, які в цьому прикладі обрані випадково). Оскільки оптимізацію не провівши через брак часу, можливі підвисання (винесення математики в веб-воркер мало б вирішити проблему).

Код візуалізації .

Опубліковано: 19/04/19 @ 10:00
Розділ Різне

Рекомендуємо:

DOU Проектор: Hurma — автоматизація HR-процесів та рекрутингу
Чим займається Developer Advocate та чому ця позиція непопулярна в Україні
Реаліті: інфо-сайт, звіт #2 (промокод на 1000 крб на контент всередині)
Job interview in English: як готуватися і що відповідати
C++ дайджест #14: Graphics API OpenGL, DirectX, Vulkan, Metal