def convert_opt_data_to_gerrychain_input(state, opt_data='', plan=None): state_df, adj_graph, _, _ = load_opt_data(state, opt_data) election_df = load_election_df(state, opt_data) state_df = state_df[['population']] metric_df = pd.concat([state_df, election_df], axis=1) if plan is not None: plan_inverse_map = {} for district_ix, tract_ixs in plan.items(): for tix in tract_ixs: plan_inverse_map[tix] = district_ix metric_df['initial_plan'] = pd.Series(plan_inverse_map, dtype=str) else: k = constants.seats[state]['house'] ideal_pop = state_df.population.sum() / k nx.set_node_attributes(adj_graph, metric_df.T.to_dict()) plan = recursive_tree_part(adj_graph, range(k), ideal_pop, 'population', 0.01) metric_df['initial_plan'] = pd.Series(plan, dtype=str) nx.set_node_attributes(adj_graph, metric_df.T.to_dict()) elections = [ Election(election, { 'Democratic': 'D_' + election, 'Republican': 'R_' + election }) for election in wrappers[state]().election_columns(include_party=False) ] return adj_graph, elections
def updaters_MC(settings): my_updaters = { "cut_edges": cut_edges, "population": updaters.Tally("TOTPOP", alias = "population"), "avg_pop_dist": avg_pop_dist, "pop_dist_pct" : pop_dist_pct, "area_land": updaters.Tally("ALAND10", alias = "area_land"), "area_water": updaters.Tally("AWATER10", alias = "area_water"), "Perimeter": updaters.Tally("perimeter", alias = "Perimeter"), "Area": updaters.Tally("area", alias = "Area")} num_elections = settings['num_elections'] election_names = settings['election_names'] election_columns = settings['election_columns'] num_steps = settings['num_steps'] interval = settings['interval'] pop_tol = settings['pop_tol'] elections = [ Election( election_names[i], {"Democratic": election_columns[i][0], "Republican": election_columns[i][1]}, ) for i in range(num_elections)] election_updaters = {election.name: election for election in elections} my_updaters.update(election_updaters) return(my_updaters)
def run_simple2(graph): election = Election("2014 Senate", { "Democratic": "sen_blue", "Republican": "sen_red" }, alias="2014_Senate") initial_partition = Partition(graph, assignment="con_distri", updaters={ "2014_Senate": election, "population": Tally("population", alias="population"), "exterior_boundaries": exterior_boundaries, "interior_boundaries": interior_boundaries, "perimeter": perimeter, "boundary_nodes": boundary_nodes, "cut_edges": cut_edges, "area": Tally("area", alias="area"), "cut_edges_by_part": cut_edges_by_part, "county_split": county_splits('county_split', "COUNTY_ID"), "black_population": Tally("black_pop", alias="black_population"), }) districts_within_tolerance_2 = lambda part: districts_within_tolerance( part, 'population', 0.3) is_valid = Validator( [single_flip_contiguous, districts_within_tolerance_2]) chain = MarkovChain( proposal=propose_random_flip, is_valid=is_valid, accept=always_accept, # accept=accept, #THe acceptance criteria is what needs to be defined ourselves - to match the paper initial_state=initial_partition, total_steps=30, ) efficiency_gaps = [] wins = [] for partition in chain: if (hasattr(partition, 'accepted') and partition.accepted): efficiency_gaps.append( gerrychain.scores.efficiency_gap(partition["2014_Senate"])) wins.append(partition["2014_Senate"].wins("Democratic")) return (efficiency_gaps, wins, partition)
"CVAP": updaters.Tally(CVAP, alias = "CVAP"), "WCVAP": updaters.Tally(WCVAP, alias = "WCVAP"), "HCVAP": updaters.Tally(HCVAP, alias = "HCVAP"), "BCVAP": updaters.Tally(BCVAP, alias = "BCVAP"), "Sum_CX": updaters.Tally(C_X, alias = "Sum_CX"), "Sum_CY": updaters.Tally(C_Y, alias = "Sum_CY"), "cut_edges": cut_edges, "demo_percents": demo_percents, "final_elec_model": final_elec_model, "num_county_splits": num_county_splits, "num_cut_edges": num_cut_edges } #updater functions elections_track = [ Election("PRES16", {"Democratic": 'ClintonD_16G_President' , "Republican": 'TrumpR_16G_President'}, alias = "PRES16"), Election("SEN16", {"Democratic": 'CampbellD_16G_US_Sen' , "Republican": 'KennedyR_16G_US_Sen'}, alias = "SEN16"), ] election_updaters = {election.name: election for election in elections_track} my_updaters.update(election_updaters) election_functions = [Election(j, candidates[j]) for j in elections] election_updaters = {election.name: election for election in election_functions} my_updaters.update(election_updaters) #initial partition######################## total_population = state_gdf[tot_pop].sum() ideal_population = total_population/num_districts if start_map == 'new_seed': start_map = recursive_tree_part(graph, range(num_districts), ideal_population, tot_pop, pop_tol, 3)
#county_col = "COUNTYFP10" pop_col = "TOTPOP" df["CPOP"] = df["TOTPOP"] - df["NCPOP"] ccol = "CPOP" uid = "ID" num_districts = 14 graph = Graph.from_geodataframe(df, ignore_errors=True) graph.add_data(df, list(df)) graph = nx.relabel_nodes(graph, df[uid]) elections = [ Election("PRES16", { "Democratic": "PRES16D", "Republican": "PRES16R" }), Election("SEN16", { "Democratic": "SEN16D", "Republican": "SEN16R" }) ] #my_updaters = {"population" : updaters.Tally("TOTPOP", alias="population")} my_updaters = { "population": Tally(pop_col, alias="population"), "cpop": Tally(ccol, alias="cpop"), "cut_edges": cut_edges } election_updaters = {election.name: election for election in elections} my_updaters.update(election_updaters)
def main(graph_json, shp, n_steps, output_dir, prefix, seed, pop_col, pop_tol, plan_col, reproject, election): os.makedirs(output_dir, exist_ok=True) has_geometry = False if not shp and not graph_json: print('Specify a shapefile or a NetworkX-format graph ' 'JSON file.', file=sys.stderr) sys.exit(1) elif shp and not graph_json: gdf = gpd.read_file(shp) if reproject: gdf = reprojected(gdf) graph = Graph.from_geodataframe(gdf) has_geometry = True elif graph_json and not shp: graph = Graph.from_json(graph_json) else: graph = Graph.from_json(graph_json) gdf = gpd.read_file(shp) if reproject: gdf = reprojected(gdf) print('Appending geometries from shapefile to graph...') graph.geometry = gdf.geometry # TODO: is this always valid? has_geometry = True my_updaters = {'population': updaters.Tally(pop_col, alias='population')} if election: election_up = Election('election', { 'Democratic': election[0], 'Republican': election[1] }) my_updaters['election'] = election_up initial_state = GeographicPartition(graph, assignment=plan_col, updaters=my_updaters) normal_chain = RecomChain(graph=graph, total_steps=n_steps, initial_state=initial_state, pop_col=pop_col, pop_tol=pop_tol, reversible=False, seed=seed) reversible_chain = RecomChain(graph=graph, total_steps=n_steps, initial_state=initial_state, pop_col=pop_col, pop_tol=pop_tol, reversible=True, seed=seed) normal_plans = [plan for plan in tqdm(normal_chain)] reversible_plans = [plan for plan in tqdm(reversible_chain)] cut_edges_fig(output_dir, prefix, normal_plans, reversible_plans) longest_boundary_fig(output_dir, prefix, normal_plans, reversible_plans) if has_geometry: demo_plans(output_dir, '_'.join([prefix, 'recom']), normal_plans, n_steps, n_steps // 25) demo_plans(output_dir, '_'.join([prefix, 'reversible_recom']), reversible_plans, n_steps, n_steps // 25) if election: election_hists(output_dir, 'dem_vote_share', 'election', 'Democratic', normal_plans, reversible_plans) acceptance_stats(output_dir, '_'.join([prefix, 'recom']), normal_plans) acceptance_stats(output_dir, '_'.join([prefix, 'reversible_recom']), reversible_plans)
"BVAP": updaters.Tally(BVAP_col, alias="BVAP"), "HVAP": updaters.Tally(HVAP_col, alias="HVAP"), "AVAP": updaters.Tally(AVAP_col, alias="AVAP"), "NVAP": updaters.Tally(Native_col, alias="NVAP"), "PVAP": updaters.Tally(Pacific_col, alias="PVAP"), "VAP": updaters.Tally(VAP_col, alias="VAP"), "county_splits": county_splits("county_splits", county_assignment_col) } num_elections = len(election_names) elections = [ Election( election_names[i], { "Dem": election_columns[i][0], "Rep": election_columns[i][1] }, ) for i in range(num_elections) ] election_updaters = {election.name: election for election in elections} updaters.update(election_updaters) # ---- Proposed Partition ----- initial_partition = GeographicPartition(graph, district_assignment_col, updaters) # ---- Chain Run ------
import numpy as np import seaborn as sns from FKT import FKT from gerrychain import (Election, Graph, MarkovChain, Partition, accept, constraints, updaters) from gerrychain.proposals import recom from gerrychain.updaters import cut_edges whole_start = time.time() # Initialization df = gpd.read_file("./AK_precincts_ns/AK_precincts_ns/AK_precincts_ns.shp") df["nAMIN"] = df["TOTPOP"] - df["AMIN"] elections = [ Election("GOV18x", {"Democratic": "GOV18D_x", "Republican": "GOV18R_x"}), Election("USH18x", {"Democratic": "USH18D_x", "Republican": "USH18R_x"}), Election("GOV18ns", {"Democratic": "GOV18D_NS", "Republican": "GOV18R_NS"}), Election("USH18ns", {"Democratic": "USH18D_NS", "Republican": "USH18R_NS"}), Election("Native_percent", {"Native": "AMIN", "nonNative": "nAMIN"}), ] my_updaters = { "population": updaters.Tally("POPULATION", alias="population"), "cut_edges": cut_edges, } election_updaters = {election.name: election for election in elections} my_updaters.update(election_updaters)
def chain(iterations): idef = random.randint(1, 10000) graph = Graph.from_json("./PA_VTD.json") election = Election("SEN12", {"Dem": "USS12D", "Rep": "USS12R"}) initial_partition = GeographicPartition(graph, assignment="2011_PLA_1", updaters={ "cut_edges": cut_edges, "population": Tally("TOT_POP", alias="population"), "SEN12": election }) ideal_population = sum( initial_partition["population"].values()) / len(initial_partition) # We use functools.partial to bind the extra parameters (pop_col, pop_target, epsilon, node_repeats) # of the recom proposal. proposal = partial(recom, pop_col="TOT_POP", pop_target=ideal_population, epsilon=0.02, node_repeats=2) chain = MarkovChain(proposal=proposal, constraints=[republican_constraint], accept=contiguous, initial_state=initial_partition, total_steps=iterations + 100) count = 0 metrics = [] boundary_nodes = [] boundary_weighted = [] for partition in chain.with_progress_bar(): mm = mean_median(partition["SEN12"]) p = pp(partition) bias = partisan_bias(partition["SEN12"]) gini = partisan_gini(partition["SEN12"]) gap = efficiency_gap(partition["SEN12"]) cut = len(partition["cut_edges"]) if count >= 100: metrics.append((mm, p, bias, gini, gap, cut)) nodes = [0] * 8921 bnodes = [0] * 8921 for edge in partition["cut_edges"]: nodes[edge[0]] = 1 nodes[edge[1]] = 1 bnodes[edge[0]] += 1 bnodes[edge[1]] += 1 boundary_nodes.append(nodes) boundary_weighted.append(bnodes) if count % 100 == 0: print(idef, count, mm, p, bias, gini, gap, cut, partition["SEN12"].wins("Rep")) count += 1 return metrics, boundary_nodes, boundary_weighted
c for c in components if len(c) != biggest_component_size ] problem_nodes = [ node for component in problem_components for node in component ] problem_geoids = [graph.nodes[node]["GEOID10"] for node in problem_nodes] is_a_problem = df["GEOID10"].isin(problem_geoids) largest_component_size = max(len(c) for c in components) to_delete = [c for c in components if len(c) != largest_component_size] for c in to_delete: for node in c: graph.remove_node(node) election = Election("PRETOT16", {"Dem": "PREDEM16", "Rep": "PREREP16"}) #Create initial parition based on congressional districts initial_partition = Partition(graph, assignment="CON", updaters={ "cut_edges": cut_edges, "population": Tally("PERSONS", alias="population"), "PRETOT16": election }) my_updaters = { "population": Tally("PERSONS", alias="population"), "PRETOT16": election
import matplotlib.pyplot as plt from gerrychain import (Election, GeographicPartition, Graph, MarkovChain, Partition, accept, constraints, proposals, updaters) from gerrychain.tree_proposals import recom # ## Setting up the initial districting plan # Load the graph we want to use. graph = Graph.from_json("./graphs/rook/PA_VTD.json") # Configure our elections, telling GerryChain which column names for our shapefiles # correspond to vote totals. elections = [ Election("SEN10", { "Democratic": "SEN10D", "Republican": "SEN10R" }), Election("SEN12", { "Democratic": "USS12D", "Republican": "USS12R" }), Election("SEN16", { "Democratic": "T16SEND", "Republican": "T16SENR" }), Election("PRES12", { "Democratic": "PRES12D", "Republican": "PRES12R" }), Election("PRES16", { "Democratic": "T16PRESD",
"BCVAP": updaters.Tally(BCVAP, alias="BCVAP"), "Sum_CX": updaters.Tally(C_X, alias="Sum_CX"), "Sum_CY": updaters.Tally(C_Y, alias="Sum_CY"), "cut_edges": cut_edges, "num_cut_edges": num_cut_edges, "num_county_splits": num_county_splits, "demo_percents": demo_percents, "final_elec_model": final_elec_model, "centroids": centroids } #add elections updaters elections_track = [ Election("PRES16", { "Democratic": 'ClintonD_16G_President', "Republican": 'TrumpR_16G_President' }, alias="PRES16"), Election("PRES12", { "Democratic": 'ObamaD_12G_President', "Republican": 'RomneyR_12G_President' }, alias="PRES12"), Election("SEN18", { "Democratic": "ORourkeD_18G_US_Sen", "Republican": 'CruzR_18G_US_Sen' }, alias="SEN18"), Election("GOV18", { "Democratic": "ValdezD_18G_Governor", "Republican": 'AbbottR_18G_Governor'
df["nBCVAP"] = df["CVAP"] - df["BCVAP"] df["BHCPOP"] = pd.to_numeric(df["BCPOP"] + df[HCPOP_cols].sum(axis=1)) df["nBHCPOP"] = df["CPOP"] - df["BHCPOP"] df["BHVAP"] = pd.to_numeric(df["BVAP"] + df[HVAP_cols].sum(axis=1)) df["nBHVAP"] = df["VAP"] - df["BHVAP"] df["BHCVAP"] = pd.to_numeric(df["BCVAP"] + df[HCVAP_cols].sum(axis=1)) df["nBHCVAP"] = df["CVAP"] - df["BHCVAP"] graph.add_data(df, columns=new_cols) elections = [ Election("BPOP", { "BPOP": "BPOP", "nBPOP": "nBPOP" }), Election("BCPOP", { "BCPOP": "BCPOP", "nBCPOP": "nBCPOP" }), Election("BVAP", { "BVAP": "BVAP", "nBVAP": "nBVAP" }), Election("BCVAP", { "BCVAP": "BCVAP", "nBCVAP": "nBCVAP" }), Election("BHPOP", { "BHPOP": "BHPOP",
["W101216D", "W101216R"], ["W1216D", "W1216R"], ] graph = Graph.from_json(graph_path) updaters = { "population": updaters.Tally("TOT_POP", alias="population"), "cut_edges": cut_edges, } elections = [ Election( election_names[i], {"Democratic": election_columns[i][0], "Republican": election_columns[i][1]}, ) for i in range(num_elections) ] election_updaters = {election.name: election for election in elections} updaters.update(election_updaters) initial_partition = Partition(graph, "2011_PLA_1", updaters) ideal_population = sum(initial_partition["population"].values()) / len( initial_partition )
ITERS = args.n EPS = epsilons[args.map] ELECTS = elections_by_year[args.year] DEMO_COLS = ["TOTPOP", "VAP", "CPOP", "CVAP", "BPOP", "HPOP", "WPOP", "BPOP_perc", "HPOP_perc", "WPOP_perc", "BCPOP", "HCPOP", "WCPOP", "BCPOP_perc", "HCPOP_perc", "WCPOP_perc", "BCVAP", "HCVAP", "WCVAP", "BCVAP_perc", "HCVAP_perc", "WCVAP_perc"] ## Pull in graph and set up updaters print("Reading in Data/Graph") with open("../graphs/GA_precincts_{}_graph.p".format(args.year), "rb") as f_in: graph = pickle.load(f_in) elections = [Election(e, {"Dem": "{}D".format(e), "Rep": "{}R".format(e)}) for e in ELECTS] ga_updaters = {"population" : Tally(POP_COL, alias="population"), "cut_edges": cut_edges, "TOTPOP": Tally("TOTPOP18", alias="TOTPOP"), "VAP": Tally("VAP18", alias="VAP"), "CPOP": Tally("CPOP18", alias="CPOP"), "CVAP": Tally("CVAP18", alias="CVAP"), "BPOP": Tally("NH_BLACK18", alias="BPOP"), "HPOP": Tally("HISP18", alias="HPOP"), "WPOP": Tally("NH_WHITE18", alias="WPOP"), "BCPOP": Tally("BCPOP18", alias="BCPOP"), "HCPOP": Tally("HCPOP18", alias="HCPOP"), "WCPOP": Tally("WCPOP18", alias="WCPOP"), "BCVAP": Tally("BCVAP18", alias="BCVAP"),
def chain(iterations): idef = random.randint(1, 10000) graph = Graph.from_json("../data/PA_init/PA_VTD.json") election = Election("SEN12", {"Dem": "USS12D", "Rep": "USS12R"}) initial_partition = GeographicPartition( graph, assignment="2011_PLA_1", updaters={ "cut_edges": cut_edges, "population": Tally("TOT_POP", alias="population"), "SEN12": election } ) ideal_population = sum(initial_partition["population"].values()) / len(initial_partition) # We use functools.partial to bind the extra parameters (pop_col, pop_target, epsilon, node_repeats) # of the recom proposal. proposal = partial(recom, pop_col="TOT_POP", pop_target=ideal_population, epsilon=0.02, node_repeats=2 ) chain = MarkovChain( proposal=proposal, constraints=[], accept=contiguous, initial_state=initial_partition, total_steps=85*iterations + 17000 ) count = 0 metrics = [] boundary_nodes = [] boundary_weighted = [] for partition in chain.with_progress_bar(): mm = mean_median(partition["SEN12"]) p = pp(partition) bias = partisan_bias(partition["SEN12"]) gini = partisan_gini(partition["SEN12"]) gap = efficiency_gap(partition["SEN12"]) cut = len(partition["cut_edges"]) if count >= 17000: if count % 85 == 0: metrics.append((mm, p, bias, gini, gap, cut, partition["SEN12"].wins("Rep"))) nodes = [0]*8921 bnodes = [0]*8921 for edge in partition["cut_edges"]: nodes[edge[0]] = 1 nodes[edge[1]] = 1 bnodes[edge[0]] += 1 bnodes[edge[1]] += 1 boundary_nodes.append(nodes) boundary_weighted.append(bnodes) assign = {i: partition.assignment[i] for i in partition.assignment} shape["CD"] = shape.index.map(assign) this_map = shape.dissolve(by='CD') this_map.plot(color='white', edgecolor='black') plt.axis('off') fig = plt.gcf() fig.set_size_inches((15,9), forward=False) fig.savefig("../images/PA_neutral/" + str(idef) + str(int((count-17000)/85)+1) + ".png", dpi=600, bbox_inches="tight", pad_inches=0) plt.close() if count % 8500 == 0: print(idef, count, mm, p, bias, gini, gap, cut, partition["SEN12"].wins("Rep")) else: if count%1000 == 0: print(idef, "Mixing...... Iteration", count, "/17000") count += 1 return metrics, boundary_nodes, boundary_weighted, idef
# In[57]: path_to_pa = r'C:\Users\adika\Downloads\PA_VTDs.json' # In[58]: from gerrychain import Graph, Partition, Election from gerrychain.updaters import Tally, cut_edges graph = Graph.from_json(path_to_pa) election = Election("SEN12", {"Dem": "USS12D", "Rep": "USS12R"}) initial_partition = Partition( graph, assignment="CD_2011", updaters={ "cut_edges": cut_edges, "population": Tally("TOTPOP", alias="population"), "SEN12": election } ) # In[59]:
totpop[i] += graph.node[n]["TOTPOP"] graph.node[n]["nBVAP"] = graph.node[n][ vap_list[i]] - graph.node[n]["BVAP"] starts = [] for i in range(4): starts.append( recursive_tree_part(graph_list[i], range(num_districts), totpop[i] / num_districts, "TOTPOP", .02, 1)) updater = { "population": updaters.Tally("TOTPOP", alias="population"), "cut_edges": cut_edges, "BVAP": Election("BVAP", { "BVAP": "BVAP", "nBVAP": "nBVAP" }) } initial_partitions = [] proposals = [] compactness_bounds = [] chains = [] for i in range(4): initial_partitions.append(Partition(graph_list[i], starts[i], updater)) proposals.append( partial(recom, pop_col="TOTPOP", pop_target=totpop[i] / num_districts,
def run_simple(graph, num_samples = 80000, wp = 3000, wi = 2.5, wc = 0.4, wm = 800, get_parts = 5): election = Election( "2014 Senate", {"Democratic": "sen_blue", "Republican": "sen_red"}, alias="2014_Senate" ) initial_partition = Partition( graph, assignment="2014_CD", updaters={ "2014_Senate": election, "population": Tally("population", alias="population"), "exterior_boundaries": exterior_boundaries, "interior_boundaries": interior_boundaries, "perimeter": perimeter, "boundary_nodes": boundary_nodes, "cut_edges": cut_edges, "area": Tally("area", alias="area"), "cut_edges_by_part": cut_edges_by_part, "county_split" : county_splits( 'county_split', "COUNTY_ID"), "black_population": Tally("black_pop", alias = "black_population"), } ) def vra_validator(part): if(vra_district_requirement(part, 2, [0.4, 0.335]) > 0): return False return True districts_within_tolerance_2 = lambda part : districts_within_tolerance(part, 'population', 0.12) is_valid = Validator([single_flip_contiguous, districts_within_tolerance_2, vra_validator ]) def accept(partition, counter): if(counter < 40000): beta = 0 elif(counter < 60000): beta = (counter - 40000) /(60000-40000) else: beta = 1 return(metro_scoring_prob(partition, beta, wp, wi, wc, wm)) chain = MarkovChainAnneal( proposal=propose_random_flip, is_valid=is_valid, accept=accept, initial_state=initial_partition, total_steps= num_samples * 100, ) # going to show 5 partitions from this sample part_con = max(1, num_samples / get_parts) efficiency_gaps = [] wins = [] voting_percents = [] sample_parts = [] tbefore = time.time() for partition in chain: if(hasattr(partition, 'accepted') and partition.accepted): efficiency_gaps.append(gerrychain.scores.efficiency_gap(partition["2014_Senate"])) wins.append(partition["2014_Senate"].wins("Democratic")) voting_percents.append(partition["2014_Senate"].percents("Democratic")) num_s = len(wins) if(num_s % part_con) == 0: sample_parts.append(partition) if(num_s> num_samples): break if(num_s % 1000 == 0): tnext = time.time() print("It took %i time to get 1000 samples" % (tnext - tbefore)) tbefore = time.time() return(efficiency_gaps, wins, voting_percents, sample_parts)
def run_simple(graph): election = Election("2016 President", { "Democratic": "T16PRESD", "Republican": "T16PRESR" }, alias="2016_President") initial_partition = Partition(graph, assignment="2011_PLA_1", updaters={ "2016_President": election, "population": Tally("TOT_POP", alias="population"), "perimeter": perimeter, "exterior_boundaries": exterior_boundaries, "interior_boundaries": interior_boundaries, "boundary_nodes": boundary_nodes, "cut_edges": cut_edges, "area": Tally("area", alias="area"), "cut_edges_by_part": cut_edges_by_part, "county_split": county_splits('county_split', "COUNTYFP10"), "black_population": Tally("BLACK_POP", alias="black_population"), }) efficiency_gaps = [] wins = [] beta = 0 wp = 1 wi = 1 wc = 0 wm = 1 def accept(partition): return (metro_scoring_prob(partition, beta, wp, wi, wc, wm)) is_valid = Validator([single_flip_contiguous, districts_within_tolerance]) chain = MarkovChain( proposal=propose_random_flip, is_valid=is_valid, #accept = always_accept, accept= accept, #THe acceptance criteria is what needs to be defined ourselves - to match the paper initial_state=initial_partition, total_steps=30) for partition in chain: if (hasattr(partition, 'accepted') and partition.accepted): efficiency_gaps.append( gerrychain.scores.efficiency_gap(partition["2016_President"])) wins.append(partition["2016_President"].wins("Democratic")) return (efficiency_gaps, wins, partition)
def MC_sample(jgraph, settings, save_part = True): """ :param jgraph: gerrychain Graph object :param settings: settings dictionary (possibly loaded from a yaml file) with election info, MC parameters, and constraints params (see settings.yaml file for an example of the structure needed) :param save_part: True is you want to save the partition as json :returns: a list of partitions sapmpled every interval step """ my_updaters = { "cut_edges": cut_edges, "population": updaters.Tally("TOTPOP", alias = "population"), "avg_pop_dist": avg_pop_dist, "pop_dist_pct" : pop_dist_pct, "area_land": updaters.Tally("ALAND10", alias = "area_land"), "area_water": updaters.Tally("AWATER10", alias = "area_water"), "Perimeter": updaters.Tally("perimeter", alias = "Perimeter"), "Area": updaters.Tally("area", alias = "Area") } num_elections = settings['num_elections'] election_names = settings['election_names'] election_columns = settings['election_columns'] num_steps = settings['num_steps'] interval = settings['interval'] pop_tol = settings['pop_tol'] MC_type = settings['MC_type'] elections = [ Election( election_names[i], {"Democratic": election_columns[i][0], "Republican": election_columns[i][1]}, ) for i in range(num_elections) ] election_updaters = {election.name: election for election in elections} my_updaters.update(election_updaters) initial_partition = Partition(jgraph, "CD", my_updaters) # by typing in "CD," we are saying to put every county into the congressional district that they belong to print('computed initial partition') ideal_population = sum(initial_partition["population"].values()) / len( initial_partition ) pop_constraint = constraints.within_percent_of_ideal_population(initial_partition, pop_tol) compactness_bound = constraints.UpperBound( lambda p: len(p["cut_edges"]), 2 * len(initial_partition["cut_edges"]) ) proposal = partial( recom, pop_col=pop_col, pop_target=ideal_population, epsilon=pop_tol, node_repeats=1) constraints_=[pop_constraint, compactness_bound] if MC_type == "flip": proposal = propose_random_flip constraints_=[single_flip_contiguous, pop_constraint, compactness_bound] chain = MarkovChain( proposal=proposal, constraints=constraints_, accept=always_accept, initial_state=initial_partition, total_steps=num_steps ) partitions=[] # recording partitions at each step for index, part in enumerate(chain): if index % interval == 0: print('Markov chain step '+str(index)) partitions += [part] if save_part: sd.dump_run(settings['partitions_path'], partitions) print('saved partitions to '+ settings['partitions_path']) return(partitions)
["D_GOV", "R_GOV"], ["D_ATTGEN", "R_ATTGEN"], ["PRES12D", "PRES12R"], ] updater = { "population": updaters.Tally("TAPERSONS", alias="population"), "cut_edges": cut_edges, 'b_nodes': b_nodes, } elections = [ Election( election_names[i], { "First": election_columns[i][0], "Second": election_columns[i][1] }, ) for i in range(num_elections) ] election_updaters = {election.name: election for election in elections} updater.update(election_updaters) initial_partition = Partition(graph, "HB5005", updater) print("built initial partition") ideal_population = sum( initial_partition["population"].values()) / len(initial_partition) # print(ideal_population)
edge_color=colors[count]) plt.savefig("va_precinct_" + str(count + 1) + ".png", bbox_inches='tight', dpi=400) plt.clf() count += 1 plt.savefig("VA_precinct_graph.png", bbox_inches='tight', dpi=400) #CD.plot(column='CD108FP', cmap='seismic') real_life_plan = Partition(graph, "CD") plt.axis('off') plt.show() plt.savefig("va_precinct_graph.png", bbox_inches='tight', dpi=400) #Gerrychain on 2016 election for virginia. graph.nodes[0] election = Election("PRES16", {"Dem": "G16DPRS", "Rep": "G16RPRS"}) initial_partition = Partition(graph, assignment="CD_16", updaters={ "cut_edges": cut_edges, "population": Tally("TOTPOP", alias="population"), "PRES16": election }) for district, pop in initial_partition["population"].items(): print("District {}: {}".format(district, pop)) from gerrychain import MarkovChain from gerrychain.constraints import single_flip_contiguous from gerrychain.proposals import propose_random_flip from gerrychain.accept import always_accept
["T16PRESD", "T16PRESR"], ["W101216D", "W101216R"], ] graph = Graph.from_json(graph_path) updaters = { "population": updaters.Tally("TOT_POP", alias="population"), "cut_edges": cut_edges, } elections = [ Election( election_names[i], { "Democratic": election_columns[i][0], "Republican": election_columns[i][1] }, ) for i in range(num_elections) ] election_updaters = {election.name: election for election in elections} updaters.update(election_updaters) initial_partition = Partition(graph, "2011_PLA_1", updaters) #Other possible starting plans are: #"2011_PLA_1": Congressional district ID in 2011 enacted congressional map #"GOV": Congressional district ID in Governor’s counter-proposed plan #"TS": Congressional district ID in Turzai-Scarnati Plan
POP_COL = "TOTPOP" NUM_DISTRICTS = num_districts_in_map[args.map] ITERS = args.n EPS = epsilons[args.map] ELECTS = ["PRES16", "SEN16", "GOV16", "GOV18", "AG16", "SOS16", "USH18"] ## Pull in graph and set up updaters print("Reading in Data/Graph") df = gpd.read_file("data/OR_precincts/OR_precincts.shp") with open("data/OR_precincts/OR_precinct_graph.p", "rb") as f_in: graph = pickle.load(f_in) elections = [Election("USH18",{"Dem": "USH18D","Rep":"USH18R"}),] Election("SEN16", {"Dem": "SEN16D", "Rep": "SEN16R"}), Election("GOV16", {"Dem": "GOV16D", "Rep": "GOV16R"}), Election("AG16", {"Dem": "AG16D", "Rep": "AG16R"}), Election("SOS16", {"Dem": "SOS16D", "Rep": "SOS16R"}), Election("GOV18", {"Dem": "GOV18D", "Rep": "GOV18R"})] or_updaters = {"population" : Tally(POP_COL, alias="population"), "cut_edges": cut_edges} election_updaters = {election.name: election for election in elections} or_updaters.update(election_updaters) ## Create seed plans and Set up Markov chain
# load actual gerrychain results sen_05 = np.load( "/Users/hopecj/projects/gerryspam/MO/res_0817/MO_state_senate_300000_0.05.p" ) sen_01 = np.load( "/Users/hopecj/projects/gerryspam/MO/res_0817/MO_state_senate_100000_0.01.p" ) sen_05.keys() # shows "columns" available print(sen_05["mean_median_ussen16"]) # results from chain # open enacted map graph = Graph.from_file( "/Users/hopecj/projects/gerryspam/MO/dat/final_prec/prec_labeled.shp") elections = [ Election("USSEN16", { "Dem": "G16USSDKAN", "Rep": "G16USSRBLU" }), Election("PRES16", { "Dem": "G16PREDCLI", "Rep": "G16PRERTRU" }) ] mo_updaters = { "population": Tally("POP10", alias="population"), "cut_edges": cut_edges } election_updaters = {election.name: election for election in elections} mo_updaters.update(election_updaters) sen_part = Partition(graph, assignment="SLDUST", updaters=mo_updaters)
"SENW101216", ] election_columns = [ ["PRES12D", "PRES12R"], ["T16PRESD", "T16PRESR"], ["W101216D", "W101216R"], ] graph = Graph.from_json(graph_path) updaters = { "population": updaters.Tally("TOT_POP", alias="population"), "cut_edges": cut_edges, "BPOP":Election("BPOP",{"BPOP":"BPOP","nBPOP":"nBPOP"}) } elections = [ Election( election_names[i], {"Democratic": election_columns[i][0], "Republican": election_columns[i][1]}, ) for i in range(num_elections) ] election_updaters = {election.name: election for election in elections} updaters.update(election_updaters)
["D_LTGOV", "R_LTGOV"], ["D_GOV", "R_GOV"], ["D_ATTGEN", "R_ATTGEN"], ["PRES12D", "PRES12R"], ] updater = { "population": updaters.Tally("TAPERSONS", alias="population"), "cut_edges": cut_edges, 'b_nodes':b_nodes, } elections = [ Election( election_names[i], {"First": election_columns[i][0], "Second": election_columns[i][1]}, ) for i in range(num_elections) ] election_updaters = {election.name: election for election in elections} updater.update(election_updaters) #with open("./Outputs/VA_Old_Tree_Plans/VA_Tree_small0198.json", 'r') as f: # tree_dict = json.load(f) #tree_dict = dict(tree_dict) #for n in graph.nodes():
"cut_edges": cut_edges, "BVAP": updaters.Tally(BVAP_col, alias = "BVAP"), "HVAP": updaters.Tally(HVAP_col, alias = "HVAP"), "AVAP": updaters.Tally(AVAP_col, alias = "AVAP"), "NVAP": updaters.Tally(Native_col, alias = "NVAP"), "PVAP": updaters.Tally(Pacific_col, alias = "PVAP"), "VAP": updaters.Tally(VAP_col, alias = "VAP"), "county_splits": county_splits("county_splits", county_assignment_col), "racial_demographics": lambda p: racial_demographics(p, "VAP", "BVAP", "HVAP", "AVAP", "NVAP", "PVAP") } num_elections = len(election_names) elections = [ Election( election_names[i], {"Dem": election_columns[i][0], "Rep": election_columns[i][1]}, ) for i in range(num_elections) ] election_updaters = {election.name: election for election in elections} updaters.update(election_updaters) # ---- Past Districting Plan ----- districting_partition = GeographicPartition(graph, district_assignment_col, updaters) compactness_ref = len(districting_partition["cut_edges"]) county_splits_ref = calc_splits(districting_partition["county_splits"]) racial_vap_ref = districting_partition["racial_demographics"]