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
示例#2
0
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)
示例#4
0
    "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)
示例#6
0
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 ------
示例#8
0
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)
示例#9
0
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
示例#10
0
        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",
示例#12
0
    "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'
示例#13
0
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",
示例#14
0
    ["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"),
示例#16
0
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]:

示例#18
0
        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,
示例#19
0
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)
示例#20
0
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)
示例#21
0
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)
示例#22
0
    ["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
示例#24
0
    ["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
示例#26
0
# 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)
示例#27
0
    "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)

示例#28
0
    ["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():
示例#29
0
    "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"]