Ranked Choice Voting Visualizer¶
Ranked Choice Voting Visualization¶
Visualize ranked-choice voting results using d3.js and django.
What is RCV? RCV allows you to rank your top candidates. As candidates get eliminated, any votes to that candidate get transferred to the voter’s next choice.
Why RCV? RCV is spreading. In an RCV election, you can’t spoil votes. Third-party candidates don’t waste votes. Similar candidates help each other instead of hurting each other. They’re less polarized and more fair. Multi-winner RCV elections mitigate the effects of gerrymandering. For more information, check out FairVote’s guide to the benefits of RCV elections.
Why the visualizer? In a traditional election, the results are easy to understand: how many votes did each candidate get? In an RCV election, it can be a harder to understand how a candidate one, based on what happens in each round. Our goal is to create a series of visualizations which can work for a variety of audiences on a variety of mediums: print, web, and TV.
Learn more on our Medium post: An Illustrated Guide to Ranked-Choice Voting.
Install python3 and virtualenv, then
virtualenv venv source venv/bin/activate pip3 install -e . pip3 install -r requirements.txt
Create a .env file with your secrets and configuration options:
export RCVIS_SECRET_KEY='' export RCVIS_DEBUG=True export RCVIS_HOST=localhost # Either have OFFLINE_MODE=True export OFFLINE_MODE=True # Or set up an AWS bucket and enter your credentials # export OFFLINE_MODE=False # export AWS_STORAGE_BUCKET_NAME='' # export AWS_S3_REGION_NAME='' # export AWS_ACCESS_KEY_ID='' # export AWS_SECRET_ACCESS_KEY='' # To run the SauceLabs integration tests, you will need export SAUCE_USERNAME='' export SAUCE_ACCESS_KEY='' # To generate videos, you need: export SQS_QUEUE_NAME='' export IMAGEIO_FFMPEG_EXE='/usr/bin/ffmpeg' export MOVIE_FONT_NAME="Roboto" export AWS_POLLY_STORAGE_BUCKET_NAME="bucket-name-on-s3"
To get moviepy working for Ubuntu 16.04 LTS users, comment out the following statement in
<policy domain="path" rights="none" pattern="@*"/>
or, simply run
To begin serving the website at localhost:8000:
source .env source venv/bin/activate python3 manage.py runserver
To run workers to generate movies (optional - only needed to use the movie generation flow):
source .env source venv/bin/activate export DISPLAY=":0" # if not already set celery -A rcvis worker --loglevel info
Addition documentation for the REST API is available at rcvis.com/api/visualizations/.
To get started with programmatic access to rcvis:
Email firstname.lastname@example.org to obtain an account.
Submit a GET request to https://www.rcvis.com/api/auth/get-token to obtain an API Key, e.g.
http GET https://www.rcvis.com/api/auth/get-token username='username' password="password".
Submit a POST request to https://www.rcvis.com/api/visualizations/ to upload a file, including the file in the
jsonFilefield of the body.
For any file uploaded via the API, you may modify it using PATCH requests.
You are limited to 1000 requests per hour as an authenticated user.
RCVIS implements the oembed protocol with discoverability, allowing you to embed files into your website with an iframe.
Functionality specifics of the Sankey diagram¶
We have added a lot of complexity to the Sankey diagram to support elections with many candidates. Let this serve both as a list of specific features, and as a list of manual tests to run whenever modifying the Sankey diagram. (Yes, we have automated integration testing, but not all of these features have integration tests yet.)
Top bar of candidate names
Sticky: On a short screen, when you scroll down far enough, it should become sticky and lock to the top of the page.
Live Candidates: The bar should by dynamic based on the candidates shown at the top of the screen, not the very first round.
As you continue to scroll down, the X positions of the candidate names should shift to continue to align with the Live Candidates.
Candidates who are not Live Candidates should be removed as you scroll down.
On a skinny screen, when you sideways scroll (particularly when it’s Sticky), the X position should continue to align with the Live Candidates.
Dragging nodes should have both the text and connected links move
Long candidate names
Candidate names should not overlap in the top bar. If a candidate name is very long, or a candidate’s number of votes makes its bar short, the name should automatically truncate to ellipses.
When you hover over these ellipses, they should reveal the candidate’s full name
There is an option to have either a horizontal or vertical sankey diagram.
- Django Visualizer
- Automatic Movie Generation
- Graph Loading & Creation
- REST API
- Common cross-app utils