Moscow DEG 2021 elections plots

Overview

Построение графиков на основе публичных данных о ДЭГ в Москве в 2021г.

Описание

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

Для кого предназначено это руководство

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

Установка

Система

Скрипты для построения графиков не должны зависеть от ОС, но на настоящий момент протестированы только под Linux. Установочные скрипты и инструкции рассчитаны на использование дистрибутивов Debian или Ubuntu. Для работы из под Windows или macOS (а для повышения безопасности и под Linux) рекомендуется воспользоваться виртуальной машиной с Ubuntu 20.04. Подойдёт например VirtualBox с вот этим образом. Установка VirtualBox достаточно проста, при необходимости инструкцию легко найти. Для подключения образа достаточно его распаковать, выполнить "Файл"-"Импорт конфигураций" и выбрать распакованный файл ova. После завершения импорта в настройках созданной виртуалки в разделе "Сеть" рекомендуется сменить тип подключения на NAT, при наличии достаточных ресурсов рекомендуется увеличить объём оперативной памяти до 8 ГБайт, остальные параметры можно оставить по-умолчанию. Системный пароль в виртуалке по ссылке выше - "ubuntu".

Клонирование репозитория и получение SQL-дампа

Для получения файлов из данного репозитория необходимо установить git и выполнить клонирование. Для этого необходимо открыть терминал (в Ubuntu нажать Activities, набрать term и нажать Enter) и выполнить в нем:

sudo apt update && sudo apt install -y git
git clone https://github.com/50000-Quaoar/election2021_msk

Для работы также понадобится дамп базы данных голосования, скачать который можно с сайта https://observer.mos.ru . Например данные по одномандатным округам доступны на этой странице, кнопка "Скачать sql dump". Если используете виртуальную машину - скачивайте сразу из неё. Данные по партийным спискам здесь.

Update: observer.mos.ru в последнее время тормозит и дампы могут скачаться битыми. Правильные дампы для голосований в Госдуму имеют в запакованном состоянии размер больше 3 ГБайт. Точно корректность дампа можно проверить следующим образом (займет несколько минут):

gunzip -kc observer-20210927_233000.sql.gz | sha256sum

SHA256 чексумма для распакованного дампа одномандатников: af3ca1f9002a7bc92065fd696e642fca84691dff7a3d8ee5165c009513082c66, а для партийных списков: 63f0cea15928ed31b1dceaaa74d2651fd901be17624bd2435ea925037fa3abec . В теории дампы после 19.09 меняться не должны, соответственно их чексуммы тоже.

Установка зависимостей и импорт базы данных

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

cd election2021_msk/install
./install_ubuntu.sh

Для импорта базы данных в том же терминале исполняем:

./import_db.sh /home/ubuntu/Downloads/observer-20210921_143000.sql.gz v2021_om

, где /home/ubuntu/Downloads/observer-20210921_143000.sql.gz - путь до скачанного дампа базы данных, а v2021_om - желаемое имя базы данных. В зависимости от производительности вашего компьютера и ресурсов виртуалки импорт может занять от нескольких минут до ~2 часов. Терминал не закрываем. Если помимо одномандатников есть желание анализировать и другие голосования (партийные списки, Мосгордума), то необходимо эту операцию повторить с другим именем файла и названием базы.

Дорасшифровывание бюллетеней

В публично доступной на https://observer.mos.ru базе данных расшифровывание бюллетеней не была произведено до конца (подробности см. например в статье на Хабре на тему ДЭГ). Чтобы исправить это прискорбное недоразумение необходимо выполнить:

cd ..
./decrypt_ballots.py --dbname v2021_om

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

Построение графиков

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

./time_plot.py -c plot-config.json --dbname v2021_om

, где plot-config.json - JSON файл с конфигурацией желаемого графика (по-умолчанию plot-config.json), а v2021_om - название базы данных. Полный help можно получить выполнив:

./time_plot.py -h

Для построения графика явки в зависимости от номера блока регистрации избирателей:

./turnout_plot.py --dbname v2021_om

, где v2021_om - название базы данных, других параметров не требуется.

Выбор данных для построения графика распределения по времени

Параметры графиков задаются в виде текстовых JSON-файлов. Параметр minutes_in_bin задаёт число минут на каждую точку по оси X (рекомендуемые значения от 10 до 60). Параметр minutes_per_axis_tick - частоту подписей времени по X. Параметр percentage выбирает отображать ли на графике абсолютное количество голосов (false) или процент голосов в данном временном интервале каждого отдельного кандидата от всех кандидатов на графике (true). Параметр integrate позволяет отобразить сумму (true) всех голосов за кандидата к текущему моменту.

Наконец наиболее важный параметр candidates_to_plot задаёт список (в квадратных скобках) ID кандидатов, которых необходимо отобразить на графике. ID интересующего вас кандидата можно узнать запустив time_plot.py с опцией -l номер_округа. Например:

./time_plot.py -l 198

выведет список кандидатов в 198 округе, а для получения полного списка используйте опцию -l 0.

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

Примеры JSON-файлов

В репозитории представлено несколько JSON файлов для примера графиков по одномандатным округам: 198_perc.json - процентное распределение голосов по времени за всех кандидатов по 198 округу; 198_integral.json - полное количество голосов к ка времени за всех кандидатов по 198 округу; 208_abs.json - распределение голосов по времени за всех кандидатов по 208 округу; sobyanin_list.json - распределение голосов по времени за всех "административных" кандидатов по всем округам Москвы, позволяет проследить схожесть динамики набора голосов, в частности т.н. "перерыв на обед" в воскресенье днем; obed.json - распределение голосов по времени за трех административных кандидатов по разным округам и трех их основных конкурентов, позволяет проследить отличие в динамике числа голосов за административных и опозиционных кандидатов, в особенности в воскресенье (стремительное набор голосов за административных в 6:30 утра, отсутствие "обеда" у опозиционных голосов и резкое снижение административных после 14:30); party.json - распределение голосов по времени по партийным спискам, обед у ЕР присутствует;

Примеры графиков

Графики для конфигураций описанных выше, некоторые приближены для наглядности.

198_perc.json

alt text

198_integral.json

alt text

208_abs.json

alt text

sobyanin_list.json

alt text

obed.json

alt text

party.json

alt text

198_perc.json нормированный на официальные результаты

alt text

turnout_plot.py для одномандатных округов

alt text

TODO

  • Добавить построение других типов графиков.
  • Ускорить расшифрование.
  • Замечания и вопросы приветствуются :).
I'm doing Genuary, an aritifiacilly generated month to build code that make beautiful things

Genuary 2022 I'm doing Genuary, an aritifiacilly generated month to build code that make beautiful things. Every day there is a new prompt for making

Joaquín Feltes 1 Jan 10, 2022
Learn Data Science with focus on adding value with the most efficient tech stack.

DataScienceWithPython Get started with Data Science with Python An engaging journey to become a Data Scientist with Python TL;DR Download all Jupyter

Learn Python with Rune 110 Dec 22, 2022
ecoglib: visualization and statistics for high density microecog signals

ecoglib: visualization and statistics for high density microecog signals This library contains high-level analysis tools for "topos" and "chronos" asp

1 Nov 17, 2021
Simple Python interface for Graphviz

Simple Python interface for Graphviz

Sebastian Bank 1.3k Dec 26, 2022
Jupyter Notebook extension leveraging pandas DataFrames by integrating DataTables and ChartJS.

Jupyter DataTables Jupyter Notebook extension to leverage pandas DataFrames by integrating DataTables JS. About Data scientists and in fact many devel

Marek Čermák 142 Dec 28, 2022
A simple agent-based model used to teach the basics of OOP in my lectures

Pydemic A simple agent-based model of a pandemic. This is used to teach basic principles of object-oriented programming to master students. It is not

Fabien Maussion 2 Jun 08, 2022
Simple addon for snapping active object to mesh ground

Snap to Ground Simple addon for snapping active object to mesh ground How to install: install the Python file as an addon use shortcut "D" in 3D view

Iyad Ahmed 12 Nov 07, 2022
Create SVG drawings from vector geodata files (SHP, geojson, etc).

SVGIS Create SVG drawings from vector geodata files (SHP, geojson, etc). SVGIS is great for: creating small multiples, combining lots of datasets in a

Neil Freeman 78 Dec 09, 2022
A Jupyter - Leaflet.js bridge

ipyleaflet A Jupyter / Leaflet bridge enabling interactive maps in the Jupyter notebook. Usage Selecting a basemap for a leaflet map: Loading a geojso

Jupyter Widgets 1.3k Dec 27, 2022
A pandas extension that solves all problems of Jalai/Iraninan/Shamsi dates

Jalali Pandas Extentsion A pandas extension that solves all problems of Jalai/Iraninan/Shamsi dates Features Series Extenstion Convert string to Jalal

51 Jan 02, 2023
Domain Connectivity Analysis Tools to analyze aggregate connectivity patterns across a set of domains during security investigations

DomainCAT (Domain Connectivity Analysis Tool) Domain Connectivity Analysis Tool is used to analyze aggregate connectivity patterns across a set of dom

DomainTools 34 Dec 09, 2022
Data Visualization Guide for Presentations, Reports, and Dashboards

This is a highly practical and example-based guide on visually representing data in reports and dashboards.

Anton Zhiyanov 395 Dec 29, 2022
GD-UltraHack - A Mod Menu for Geometry Dash. Specifically a MegahackV5 clone in Python. Only for Windows

GD UltraHack: The Mod Menu that Nobody asked for. This is a mod menu for the gam

zeo 1 Jan 05, 2022
Matplotlib JOTA style for making figures

Matplotlib JOTA style for making figures This repo has Matplotlib JOTA style to format plots and figures for publications and presentation.

JOTA JORNALISMO 2 May 05, 2022
A high-level plotting API for pandas, dask, xarray, and networkx built on HoloViews

hvPlot A high-level plotting API for the PyData ecosystem built on HoloViews. Build Status Coverage Latest dev release Latest release Docs What is it?

HoloViz 694 Jan 04, 2023
Interactive plotting for Pandas using Vega-Lite

pdvega: Vega-Lite plotting for Pandas Dataframes pdvega is a library that allows you to quickly create interactive Vega-Lite plots from Pandas datafra

Altair 342 Oct 26, 2022
Visualize large time-series data in plotly

plotly_resampler enables visualizing large sequential data by adding resampling functionality to Plotly figures. In this Plotly-Resampler demo over 11

PreDiCT.IDLab 604 Dec 28, 2022
Sparkling Pandas

SparklingPandas SparklingPandas aims to make it easy to use the distributed computing power of PySpark to scale your data analysis with Pandas. Sparkl

366 Oct 27, 2022
A command line tool for visualizing CSV/spreadsheet-like data

PerfPlotter Read data from CSV files using pandas and generate interactive plots using bokeh, which can then be embedded into HTML pages and served by

Gino Mempin 0 Jun 25, 2022
This is a Boids Simulation, written in Python with Pygame.

PyNBoids A Python Boids Simulation This is a Boids simulation, written in Python3, with Pygame2 and NumPy. To use: Save the pynboids_sp.py file (and n

Nik 17 Dec 18, 2022