-
Notifications
You must be signed in to change notification settings - Fork 12
Getting started with a chain
We'll start by showing a block of code that runs a simple chain, and then we'll break down what each section is doing afterwards. If you want to run this code, you can copy and paste the provided code into a file (for example, main.jl) at the root directory of the repository. Then, you can run it by navigating to the repository and running julia main.jl from the commmand line.
include("./src/GerryChain.jl")
using .GerryChain
SHAPEFILE_PATH = "./PA_VTD.json"
POPULATION_COL = "TOT_POP"
ASSIGNMENT_COL = "538GOP_PL"
# Initialize graph and partition
graph = BaseGraph(SHAPEFILE_PATH, POPULATION_COL , ASSIGNMENT_COL)
partition = Partition(SHAPEFILE_PATH, graph, POPULATION_COL, ASSIGNMENT_COL)
# Define parameters of chain (number of steps and population constraint)
pop_constraint = PopulationConstraint(graph, POPULATION_COL, 0.02)
num_steps = 10
# Initialize Election of interest
election = Election("SEN10", ["SEN10D", "SEN10R"], graph.num_dists)
# Define scores
partisan_metrics = [
efficiency_gap("efficiency_gap", election, "SEN10D"),
seats_won("seats_won", election, "SEN10D"),
mean_median("mean_median", election, "SEN10D")
]
scores = [
DistrictAggregate("presd", "PRES12D"),
ElectionTracker(election, partisan_metrics)
]
println("Running 10-step ReCom chain...")
score_vals = recom_chain(graph, partition, pop_constraint, num_steps, scores)
graph = BaseGraph(SHAPEFILE_PATH, POPULATION_COL , ASSIGNMENT_COL)
partition = Partition(SHAPEFILE_PATH, graph, POPULATION_COL, ASSIGNMENT_COL)
We read in the graph from a shapefile, which is a file that contains a lot of information about the various precincts in our area of interest. It contains information such as which precincts are adjacent to each other, the voting totals of each precinct in various elections, demographic characteristics of each precinct, etc. This information is stored in the graph object. Imagine the graph object as storing the "ground truth" about the precincts in an area. We pass in the name of the column in the shapefile that contains the population of each precinct as well as the name of the column that contains the initial assignment of precincts to districts.
On the other hand, the partition object is designed to do just that: contain many-to-one mapping of nodes in our graph to districts. Partition is just a fancy way of saying "assigning places to districts" - in other words, a districting plan! The Markov chain has to start somewhere, so the initial partition is the districting plan at the start of the chain. We pass in the same additional arguments (name of the population column and name of the assignment column), because we need to know (a) how many people are in each district and (b) the initial plan.
pop_constraint = PopulationConstraint(graph, POPULATION_COL, 0.02)
num_steps = 10
We will (eventually) pass in the population constraint to our chain as a way to ensure that the plans generated by the chain do not create districts that have unacceptable levels of population imbalance. Here, we are allowing each district to have a population that deviates from a maximum of 2% from the total population divided by the number of districts. We also declare that the number of steps that will be taken by the chain is 10. Since there are 10 steps that will be taken, we will generate 10 new plans. That means the chain is composed of a total of 11 plans - 1 initial plan and 10 generated plans.
election = Election("SEN10", ["SEN10D", "SEN10R"], graph.num_dists)
Oftentimes, a key part of an analysis that uses GerryChain is measuring the election outcomes across our different districting plans. We first define an Election object, which we pass a name, the columns in our shapefile that correspond to the vote counts for each party, and the number of districts in the plan.
partisan_metrics = [
efficiency_gap("efficiency_gap", election, "SEN10D"),
seats_won("seats_won", election, "SEN10D"),
mean_median("mean_median", election, "SEN10D")
]
scores = [
DistrictAggregate("presd", "PRES12D"),
ElectionTracker(election, partisan_metrics)
]