def preprocessing(path_to_json):
    """Takes file path to JSON graph, and returns the appropriate 

    Args:
        path_to_json (String): path to graph in JSON format

    Returns:
        graph (Gerrychain Graph): graph in JSON file following cleaning
        dual (Gerrychain Graph): planar dual of graph
    """
    graph = Graph.from_json(path_to_json)
    # For each node in graph, set 'pos' parameter to position
    for node in graph.nodes():
        graph.nodes[node]['pos'] = (graph.nodes[node][config['X_POSITION']],
                                    graph.nodes[node][config['Y_POSITION']])

    save_fig(graph, config['UNDERLYING_GRAPH_FILE'], config['WIDTH'])

    # Cleans graph to be able to find planar dual
    # TODO: why is this necessary?
    #graph = duality_cleaning(graph)

    print('Making Dual')
    dual = facefinder.restricted_planar_dual(graph)
    print('Made Dual')

    return graph, dual
def main(config_data, id):
    try:
        timeBeg = time.time()
        print('Experiment', id, 'has begun')
        # Save configuration into global variable
        global config
        config = config_data

        graph = Graph.from_json(config['INPUT_GRAPH_FILENAME'])

        # List of districts in original graph
        parts = list(
            set([
                graph.nodes[node][config['ASSIGN_COL']]
                for node in graph.nodes()
            ]))
        # Ideal population of districts
        ideal_pop = sum(
            [graph.nodes[node][config['POP_COL']]
             for node in graph.nodes()]) / len(parts)

        election = Election(config['ELECTION_NAME'], {
            'PartyA': config['PARTY_A_COL'],
            'PartyB': config['PARTY_B_COL']
        })

        updaters = {
            'population': Tally(config['POP_COL']),
            'cut_edges': cut_edges,
            config['ELECTION_NAME']: election
        }

        partDict = recursive_tree_part(graph, parts, ideal_pop,
                                       config['POP_COL'], config['EPSILON'],
                                       config['NODE_REPEATS'])
        for node in graph.nodes():
            graph.nodes[node][config['ASSIGN_COL']] = partDict[node]
        part = Partition(graph=graph,
                         assignment=config['ASSIGN_COL'],
                         updaters=updaters)
        for len_ in config['RUN_LENGTHS']:
            for num in range(config['RUNS_PER_LEN']):
                run_chain(part, config['CHAIN_TYPE'], len_, ideal_pop,
                          '{}_{}_{}_{}'.format(config['TAG'], id, len_, num))

        print('Experiment {} completed in {} seconds'.format(
            id,
            time.time() - timeBeg))

    except Exception as e:
        # Print notification if any experiment fails to complete
        track = traceback.format_exc()
        print(track)
        print('Experiment {} failed to complete after {:.2f} seconds'.format(
            id,
            time.time() - timeBeg))
Beispiel #3
0
def test():

    graph_path = "./Data/PA_VTDALL.json"
    graph = Graph.from_json(graph_path)
    k = 18
    ep = 0.05
    unit_id = "GEOID10"
    pop_col = "TOT_POP"

    plot_path = "./Data/VTD_FINAL"
    unit_df = gpd.read_file(plot_path)
    division_col = "COUNTYFP10"
    divisions = unit_df[[division_col, 'geometry']].dissolve(by=division_col,
                                                             aggfunc='sum')

    updaters = {"population": updaters.Tally(pop_col, alias="population")}
    cddict = recursive_tree_part(graph,
                                 range(k),
                                 df[pop_col].sum() / k,
                                 pop_col,
                                 .01,
                                 node_repeats=1)
    initial_partition = Partition(graph, cddict, updaters)
    ideal_population = sum(
        initial_partition["population"].values()) / len(initial_partition)
    division_proposal = partial(recom,
                                pop_col=pop_col,
                                pop_target=ideal_population,
                                epsilon=0.05,
                                method=partial(division_bipartition_tree,
                                               division_col=division_col),
                                node_repeats=2)

    chain = MarkovChain(proposal=division_proposal,
                        constraints=[
                            constraints.within_percent_of_ideal_population(
                                initial_partition, 0.05),
                        ],
                        accept=accept.always_accept,
                        initial_state=initial_partition,
                        total_steps=1000)

    t = 0
    snapshot = 100
    for part in chain:
        if t % snapshot == 0:
            draw_graph(graph,
                       part.assignment,
                       unit_df,
                       divisions,
                       './chain_' + str(t) + '.png',
                       geo_id=unit_id)
        t += 1
Beispiel #4
0
def test_pa_freeze():
    from gerrychain import (
        GeographicPartition,
        Graph,
        MarkovChain,
        proposals,
        updaters,
        constraints,
        accept,
    )
    import hashlib
    from gerrychain.proposals import recom
    from functools import partial

    graph = Graph.from_json("docs/user/PA_VTDs.json")

    my_updaters = {"population": updaters.Tally("TOTPOP", alias="population")}
    initial_partition = GeographicPartition(graph,
                                            assignment="CD_2011",
                                            updaters=my_updaters)

    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="TOTPOP",
                       pop_target=ideal_population,
                       epsilon=0.02,
                       node_repeats=2)

    pop_constraint = constraints.within_percent_of_ideal_population(
        initial_partition, 0.02)

    chain = MarkovChain(
        proposal=proposal,
        constraints=[pop_constraint],
        accept=accept.always_accept,
        initial_state=initial_partition,
        total_steps=100,
    )

    result = ""
    for count, partition in enumerate(chain):
        result += str(list(sorted(partition.population.values())))
        result += str(len(partition.cut_edges))
        result += str(count) + "\n"

    assert hashlib.sha256(result.encode()).hexdigest(
    ) == "3bef9ac8c0bfa025fb75e32aea3847757a8fba56b2b2be6f9b3b952088ae3b3c"
Beispiel #5
0
def preprocessing(path_to_json):
    graph = Graph.from_json(path_to_json)
    for node in graph.nodes():
        graph.nodes[node]['pos'] = [ graph.nodes[node]["C_X"], graph.nodes[node]["C_Y"] ]
    graph = duality_cleaning(graph)
    print("making dual")
    dual = restricted_planar_dual(graph)
    print("made dual")
    
    save_fig(graph,"./plots/UnderlyingGraph.png",1)
    
    for node in graph.nodes():
        graph.nodes[node]["population"] = graph.nodes[node]["TOTPOP"]


    return graph, dual
def preprocessing(path_to_json):
    """Takes file path to JSON graph, and returns the appropriate

    Args:
        path_to_json ([String]): path to graph in JSON format

    Returns:
        graph (Gerrychain Graph): graph in JSON file following cleaning
        dual (Gerrychain Graph): planar dual of graph
    """
    graph = Graph.from_json(path_to_json)
    # For each node in graph, set 'pos' keyword to position
    for node in graph.nodes():
        graph.nodes[node]['pos'] = (graph.nodes[node][config['X_POSITION']],
                                    graph.nodes[node][config['Y_POSITION']])

    save_fig(graph, config['UNDERLYING_GRAPH_FILE'], config['WIDTH'])

    dual = facefinder.restricted_planar_dual(graph)

    return graph, dual
Beispiel #7
0
def preprocessing(path_to_json, output_directory):
    """Takes file path to JSON graph, and returns the appropriate

    Args:
        path_to_json ([String]): path to graph in JSON format
        output_directory: path of directory to save output in 
    Returns:
        graph (Gerrychain Graph): graph in JSON file following cleaning
        dual (Gerrychain Graph): planar dual of graph
    """
    graph = Graph.from_json(path_to_json)
    # For each node in graph, set 'pos' keyword to position
    for node in graph.nodes():
        graph.nodes[node]['pos'] = (graph.nodes[node][config['X_POSITION']],
                                    graph.nodes[node][config['Y_POSITION']])

    save_fig(graph, output_directory + '/UnderlyingGraph.png', config['WIDTH'])
    #restricted planar dual does not include unbounded face
    dual = facefinder.restricted_planar_dual(graph)

    return graph, dual
from sklearn import manifold
from sklearn.metrics import euclidean_distances
from sklearn.decomposition import PCA
from gerrychain import Graph
import geopandas as gpd
from gerrychain.tree import recursive_tree_part
from gerrychain.partition import Partition
from gerrychain.updaters import Tally, cut_edges
from gerrychain.updaters import Election
from gerrychain.metrics import efficiency_gap, mean_median
import random
import time

start_time = time.time()
g = Graph.from_json("./Data/PA_VTD.json")
df = gpd.read_file("./Data/PA_VTD.shp")
centroids = df.centroid
c_x = centroids.x
c_y = centroids.y
shape = True

nlist = list(g.nodes())
n = len(nlist)

totpop = 0
for node in g.nodes():
    g.node[node]["TOT_POP"] = int(g.node[node]["TOT_POP"])

    totpop += g.node[node]["TOT_POP"]
Beispiel #9
0
 csvwriter.writerow(fields)
 
 for state in state_codes.keys():
     for impose_contiguity in {True,False}:
     
         ###########################
         # INPUTS 
         ###########################
         
         k = congressional_districts_2010[state]
         
         # Read county-level graph from "<state>_county.json"
         filepath = "C:\\districting-data-2010\\"
         filename = state + '_county.json'
         
         G = Graph.from_json( filepath + filename )
         
         DG = nx.DiGraph(G) # bidirected version of G
         
         deviation = 0.01 # +/- 0.5%
         
         total_population = sum( G.nodes[i]['TOTPOP'] for i in G.nodes )
         
         L = math.ceil((1-deviation/2)*total_population/k)
         U = math.floor((1+deviation/2)*total_population/k)
         
         print("L =",L,"U =",U,"k =",k)
         
         row = [state,G.number_of_nodes(),G.number_of_edges(),k,L,U,impose_contiguity]
         
         ###########################
Beispiel #10
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
Beispiel #11
0
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 15 13:41:51 2019

@author: daryl
"""

import networkx as nx
from gerrychain import Graph
import matplotlib.pyplot as plt
g = Graph.from_json("./BG05.json")

n = len(g.nodes())

triangles = []
maxdeg = []
number_leaves = []
diam = []
number_edges = []

for i in range(100):
    w = nx.waxman_graph(n, 1.25)
    triangles.append(sum(nx.triangles(w).values()))
    maxdeg.append(max(dict(nx.degree(w)).values()))
    number_leaves.append(sum([nx.degree(w)[node] == 1 for node in w.nodes()]))
    if nx.is_connected(w):
        diam.append(nx.diameter(w))
    number_edges.append(len(w.edges()))

plt.figure()
plt.hist(triangles)
Beispiel #12
0
def most_rep_districts(json, num_dists, election, D):
    graph = Graph.from_json("./" + json + ".json")

    TOTPOP = "TOTPOP"
    DEMVOTE = election + "D"
    REPVOTE = election + "R"

    # Ensure data are integers
    if election != "PRES16":
        for n in graph.nodes:
            if type(graph.nodes[n][DEMVOTE]) != int:
                graph.nodes[n][DEMVOTE] = int(graph.nodes[n][DEMVOTE].replace(
                    ",", ""))
            if type(graph.nodes[n][REPVOTE]) != int:
                graph.nodes[n][REPVOTE] = int(graph.nodes[n][REPVOTE].replace(
                    ",", ""))

    # Find the ideal population I
    pop_count = 0
    for i in graph.nodes:
        pop_count += graph.nodes[i][TOTPOP]
    pop_count = np.round(pop_count)
    I = (pop_count / num_dists)

    # Create lists of total pop, dem, and rep voters per precinct
    prec_pop = []
    prec_dem = []
    prec_rep = []
    for n in graph.nodes:
        prec_pop.append(graph.nodes[n][TOTPOP])
        prec_rep.append(graph.nodes[n][REPVOTE])
        prec_dem.append(graph.nodes[n][DEMVOTE])

    # Create a sorted list of deltas according to a specific, hard-coded metric

    deltas = []
    for i in range(len(prec_pop)):
        if prec_pop[i] != 0:
            deltas.append([(prec_rep[i] - prec_dem[i]) / prec_pop[i], i])

    rep_deltas = sorted(deltas, reverse=True)
    rep_node_list = []

    # Greedily create precincts
    pop_counter = 0
    for i in range(len(prec_pop)):
        if 0 <= pop_counter < D * I:
            rep_node_list.append(rep_deltas[i][1])
            pop_counter += graph.nodes[rep_deltas[i][1]][TOTPOP]

    dem_votes = 0
    rep_votes = 0
    total_pop = 0

    for m in range(len(rep_node_list)):
        dem_votes += graph.nodes[rep_node_list[m]][DEMVOTE]
        rep_votes += graph.nodes[rep_node_list[m]][REPVOTE]
        total_pop += graph.nodes[rep_node_list[m]][TOTPOP]

    pct = rep_votes / (dem_votes + rep_votes)

    print("For", json, election, ":")
    print("The most Republican quasi-district of size", D, "possible is", pct,
          "Republican")
Beispiel #13
0
import json
from gerrychain import (
    Election,
    Graph,
    MarkovChain,
    Partition,
    accept,
    constraints,
    updaters,
)
from gerrychain.tree import recursive_tree_part
import numpy as np
import pickle
import wasserplan

graph = Graph.from_json("NC_VTD.json")


def get_partition(partition_file, fid_to_geoid_file, geoidcol):
    fid_to_node = get_fid_to_node(fid_to_geoid_file, geoidcol)
    fid_to_district = {}
    f = open(partition_file, 'r')
    for line in f:
        lineitems = line.rstrip("\n").split("\t")
        fid, district = int(lineitems[0]) + 1, int(lineitems[1])
        fid_to_district[fid] = district
    assignment = {}
    for fid in fid_to_district:
        assignment[
            fid_to_node[fid]] = fid_to_district[fid] - 1  #make 0-indexed
    return assignment
    # fill-in unspecified configs using default values
    for ckey in available_config.keys():
        if ckey not in config.keys():
            print("Using default value", ckey, "=", default_config[ckey],
                  "since no option was selected.")
            config[ckey] = default_config[ckey]

    # initialize dictionary to store this run's results
    result = config
    result['run'] = key

    # read input data
    state = config['state']
    code = state_codes[state]
    level = config['level']
    G = Graph.from_json("../data/" + level + "/dual_graphs/" + level + code +
                        ".json")
    DG = nx.DiGraph(G)  # bidirected version of G
    df = gpd.read_file("../data/" + level + "/shape_files/" + state + "_" +
                       level + ".shp")

    # set parameters
    k = number_of_congressional_districts[state]
    population = [G.nodes[i]['TOTPOP'] for i in G.nodes()]
    deviation = 0.01
    U = math.floor((1 + deviation / 2) * (sum(population) / k))
    L = math.ceil((1 - deviation / 2) * (sum(population) / k))
    ideal = math.floor(sum(population) / k)

    print("k =", k)
    result['k'] = k
    result['n'] = G.number_of_nodes()
Beispiel #15
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)
Beispiel #16
0
    "congress_2010": 13,
    "state_senate": 56,
    "state_house": 180
}

POP_COL = args.popcol
NUM_DISTRICTS = num_districts_in_map[args.map]
ITERS = 10000

## Setup graph, updaters, elections, and initial partition

print("Reading in Data/Graph")

# shapefile = "../data/maupped_ga_2016_precincts/maupped_ga_2016_precincts.shp"
df = gpd.read_file("../data/ga_2012_tract.shp")
graph = Graph.from_json("../data/ga_tract.json")

new_cols = [
    "CPOP", "VAP", "BVAP", "nBVAP", "CVAP", "BCVAP", "nBCVAP", "BHVAP",
    "nBHVAP", "BHCVAP", "nBHCVAP", "BHPOP", "nBHPOP"
]

BCPOP_cols = [
    "MNVVAPBLK", "MNLVAPBLK", "FNVVAPBLK", "FNLVAPBLK", "MNVU18BLK",
    "MNLU18BLK", "FNVU18BLK", "FNLU18BLK"
]
VAP_cols = ["MVAPTOT", "FVAPTOT"]
BVAP_cols = ["MVAPBLK", "FVAPBLK"]
CVAP_cols = ["MNVVAPTOT", "MNLVAPTOT", "FNVVAPTOT", "FNLVAPTOT"]
BCVAP_cols = ["MNVVAPBLK", "MNLVAPBLK", "FNVVAPBLK", "FNLVAPBLK"]
Beispiel #17
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
# # Running a chain with ReCom

from functools import partial

import pandas

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"
    }),
def demo():
    graph_path = "./Data/PA_VTDALL.json"
    graph = Graph.from_json(graph_path)
    k = 18
    ep = 0.05
    pop_col = "TOT_POP"

    plot_path = "./Data/VTD_FINAL"
    unit_df = gpd.read_file(plot_path)
    unit_col = "GEOID10"
    division_col = "COUNTYFP10"
    divisions = unit_df[[division_col, 'geometry']].dissolve(by=division_col,
                                                             aggfunc='sum')
    county_dict = pd.Series(unit_df[division_col].values,
                            index=unit_df[unit_col]).to_dict()

    for v in graph.nodes:
        graph.nodes[v]['division'] = county_dict[v]
        graph.nodes[v][unit_col] = v

    updaters = {
        "population": Tally("TOT_POP", alias="population"),
        "cut_edges": cut_edges,
    }
    cddict = recursive_tree_part(graph,
                                 range(k),
                                 unit_df[pop_col].sum() / k,
                                 pop_col,
                                 .01,
                                 node_repeats=1)
    initial_partition = Partition(graph, cddict, updaters)
    ideal_population = sum(
        initial_partition["population"].values()) / len(initial_partition)
    division_proposal = partial(recom,
                                pop_col=pop_col,
                                pop_target=ideal_population,
                                epsilon=0.05,
                                method=partial(division_bipartition_tree,
                                               division_col='division'),
                                node_repeats=2)

    chain = MarkovChain(proposal=division_proposal,
                        constraints=[
                            constraints.within_percent_of_ideal_population(
                                initial_partition, 0.05),
                        ],
                        accept=accept.always_accept,
                        initial_state=initial_partition,
                        total_steps=1000)

    t = 0
    snapshot = 100
    for part in chain:
        if t % snapshot == 0:
            draw_graph(graph,
                       part.assignment,
                       unit_df,
                       divisions,
                       './figs/chain_' + str(t) + '.png',
                       geo_id=unit_col)
            print(
                "t: ", t, ", num_splits: ",
                num_splits(part,
                           unit_df,
                           geo_id=unit_col,
                           division_col=division_col), ", cut_length",
                cut_length(part))
        t += 1
Beispiel #20
0
#############

#for state in list(range(1,1+56)) + [72]:  # all FIPS codes
for state in [19, 25, 5]:
    # ignore invalid FIPS codes:
    if state in [3, 7, 14, 36, 43, 52]:
        continue
    #else

    #--------------------------#
    # Data Formatting Subblock #
    #--------------------------#

    statecode = str(state).zfill(2)  # makes 'state' into a 2-digit string
    levelcode = LEVEL + statecode
    g = Graph.from_json(indir_graph + levelcode + ".json")
    df = gpd.read_file(indir_df + levelcode + ".shp")

    centroids = df.centroid
    c_x = centroids.x
    c_y = centroids.y
    pos = {node: (c_x[node], c_y[node]) for node in g.nodes}

    #--------------------------#
    # Graph-Building Subblock  #
    #  (see face_graphs above) #
    #--------------------------#

    print("generating graphs for FIPS " + statecode)
    rgraph, tgraph = face_graphs(g, df)
Beispiel #21
0
    for element in ['boxes', 'whiskers', 'medians', 'caps']:
        plt.setp(bp[element], color=edge_color, zorder=4)
    for patch in bp['boxes']:
        patch.set(facecolor=fill_color, zorder=0)


state_abbr = "AR"
state_fip = "05"
num_districts = 4

newdir = "./Outputs/" + state_abbr + "/"
os.makedirs(os.path.dirname(newdir + "init.txt"), exist_ok=True)
with open(newdir + "init.txt", "w") as f:
    f.write("Created Folder")

County_graph = Graph.from_json("./County/dual_graphs/County" + state_fip +
                               ".json")
COUSUB_graph = Graph.from_json("./County_Subunits/COUSUB" + state_fip +
                               ".json")
Tract_graph = Graph.from_json("./Tracts/Tract" + state_fip + ".json")
BG_graph = Graph.from_json("./Block_Groups/BG" + state_fip +
                           ".json")  #("./Tracts/Tract"+state_fip+".json")#

unique_label = "GEOID10"
pop_col = "TOTPOP"

graph_list = [BG_graph, COUSUB_graph, Tract_graph, County_graph]

vap_list = ["VAP", "VA", "VAP", "VAP"]
totpop = [0, 0, 0, 0]
for i in range(4):
    graph = graph_list[i]
get_ipython().system('ls GerryChain/docs/user/PA_VTDs.json')


# 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]:
Beispiel #23
0
county_col = "COUNTYFP10"

num_elections = 3

election_names = [
    "PRES12",
    "PRES16",
    "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,
}

elections = [
    Election(
        election_names[i],
        {
            "Democratic": election_columns[i][0],
            "Republican": election_columns[i][1]
        },
    ) for i in range(num_elections)
]
Beispiel #24
0
    for d2 in range(10):
        if str(d1)+str(d2) in ["00","03","07","14","43","52","06","12","17"] or d1==5 and d2>6:
        
            continue
        else:

            bg_fips = "BG"+str(d1)+str(d2)
"""
The Block json can be read directly from the vrdi git hub using the commented code that follows
"""            
###            url = "https://raw.githubusercontent.com/vrdi/Your-State/master/Block_Groups/"+bg_fips+".json"
###            directory = "/home/cleveland/Desktop/VRDI2/My_State/NetworksWeek5/UvR/BG_Json/"
###            filename = directory + bg_fips+".json"
###            urllib.request.urlretrieve(url, filename)
###            g = Graph.from_json(filename)
            g = Graph.from_json("/media/cleveland/ea722593-dc05-41aa-8b50-9ac3c60c0aa7/Census_Shapefiles/Census_Shapefiles/Your-State/Block_Groups/"+bg_fips+".json")
            df = gpd.read_file("/media/cleveland/ea722593-dc05-41aa-8b50-9ac3c60c0aa7/Census_Shapefiles/Census_Shapefiles/BG/"+bg_fips+".shp")
            centroids = df.centroid
            c_x = centroids.x
            c_y = centroids.y
            shape = True

            nlist = list(g.nodes())
            n = len(nlist)

### shuffle = True
            shuffle = False

            num_steps = 100

            pos = nx.kamada_kawai_layout(g)
Beispiel #25
0
from numpy import linalg as LA
import matplotlib.pyplot as plt
from sklearn.cluster import SpectralClustering
from sklearn import metrics
from networkx.algorithms.community import greedy_modularity_communities
from networkx.algorithms.community import label_propagation_communities
from gerrychain import Graph

import geopandas as gpd

G = nx.karate_club_graph()
n = 34
G = nx.grid_graph([5, 5])
n = 25

G = Graph.from_json("./County05.json")
n = len(list(G.nodes()))
df = gpd.read_file("./County05.shp")

AM = nx.adjacency_matrix(G)
NLM = (nx.normalized_laplacian_matrix(G)).todense()
LM = (nx.laplacian_matrix(G)).todense()
'''
Labels = [G.nodes[i]['club'] != 'Mr. Hi' for i in G.nodes()]


plt.figure()
plt.title("Data Labels")
nx.draw(G, node_color=Labels )
plt.show()
'''
Beispiel #26
0
def preprocessing(url):
    maps = [ "https://people.csail.mit.edu/ddeford/COUSUB/COUSUB_13.json", "https://people.csail.mit.edu/ddeford/COUSUB/COUSUB_55.json", "https://people.csail.mit.edu/ddeford/COUNTY/COUNTY_13.json"]

    # #extract_github_data(url)
    # data = gpd.read_file("data/NC_VTD.shp")
    # data.set_index("VTD", inplace=True)
    # problems = ['3702144.1', '3705722', '37163LAKE', '37179041', '37193108']
    # for problem in problems:
    #     data.loc[problem, "geometry"] = data.loc[problem, "geometry"].buffer(0)
    # graph = Graph.from_geodataframe(data)
    # graph.add_data(data)
    ## using daryls population balanced graph 
    graph = Graph.from_json("jsons/NC.json")
    #pos = {node: [c_x[node], c_y[node]] for node in graph.nodes}
    for node in graph.nodes():
        graph.nodes[node]['pos'] = [ graph.nodes[node]["C_X"], graph.nodes[node]["C_Y"] ]
    print(nx.check_planarity(graph))

    #Have to remove bad nodes in order for the duality thing to work properly
    

    cleanup = True
    while cleanup:
        print("clean up phase")
        print(len(graph))
        deg_one_nodes = []
        for v in graph.nodes():
            if graph.degree(v) == 1:
                deg_one_nodes.append(v)
        graph.remove_nodes_from(deg_one_nodes)
        
        deg_2_nodes = []
        for v in graph.nodes():
            if graph.degree(v) == 2:
                deg_2_nodes.append(v)
    
        for v in deg_2_nodes:
            graph = smooth_node(graph, v)    
        
        bad_nodes = []
        for v in graph.nodes():
            if graph.degree(v) == 1 or graph.degree(v) == 2:
                bad_nodes.append(v)
        if len(bad_nodes) > 0:
            cleanup = True
        else:
            cleanup = False
        
    print(len(graph))
    print("making dual")
    dual = restricted_planar_dual(graph)
    print("made dual")
    plt.figure()
    nx.draw(graph, pos=nx.get_node_attributes(graph, 'pos'), node_size = 1, width = 1, cmap=plt.get_cmap('jet'))
    plt.savefig("./plots/UnderlyingGraph.png", format='png')
    plt.close()
    
    
    for node in graph.nodes():
        graph.nodes[node]["population"] = graph.nodes[node]["TOTPOP"]


    return graph, dual
import matplotlib.pyplot as plt
import random
import numpy as np
from gerrychain import Graph
import geopandas as gpd
from gerrychain.tree import recursive_tree_part
from gerrychain.partition import Partition
from gerrychain.updaters import Tally, cut_edges

g = nx.grid_graph([10, 10])

g = nx.karate_club_graph()

ns = 50

g = Graph.from_json("./Data/BG05.json")
df = gpd.read_file("./Data/BG05.shp")
centroids = df.centroid
c_x = centroids.x
c_y = centroids.y
shape = True

nlist = list(g.nodes())
n = len(nlist)

totpop = 0
for node in g.nodes():
    g.node[node]["TOTPOP"] = int(g.node[node]["TOTPOP"])

    totpop += g.node[node]["TOTPOP"]
Beispiel #28
0
    tot_pop = sum(
        [part['population'][i] for i in range(1, number_of_wards + 1)])
    for i in range(1, number_of_wards + 1):
        p = part['population'][i]
        if p == 0: continue
        r_pop = part[R][i] / p
        if r_pop == 0 or r_pop == 1: continue
        entropy = -(r_pop) * math.log(r_pop)
        entropy -= (1 - r_pop) * math.log(1 - r_pop)
        numerator += (p / tot_pop) * entropy
    r_pop = sum([part[R][i] for i in range(1, number_of_wards + 1)]) / tot_pop
    denominator = -r_pop * math.log(r_pop) - (1 - r_pop) * math.log(1 - r_pop)
    return numerator / denominator


graph = Graph.from_json(map_json_file)

data = []
for i in range(10000, 15000):
    if i % 100 == 0:
        print(i)
    with open("./res/chicago_assignments/assignment%05d.json" % i) as f:
        assignments = json.load(f)
        for n in graph.nodes():
            graph.nodes[n]['assignment'] = assignments[graph.nodes[n]
                                                       ['JOINID']] + 1

        part = Partition(graph, 'assignment', myupdaters)

        data.append(
            dict([(l, segregation(graph, part, l))
Beispiel #29
0
def slow_reversible_propose(partition):

    flip = random.choice(list(partition["b_nodes"]))
    
    return partition.flip({flip[0]: flip[1]})

#graph = Graph.from_file("./State_Data/VA_Trimmed.shp")


#with open("./State_Data/VA_Trimmedj.json", 'w') as outfile:
#    json.dump(json_graph.adjacency_data(graph), outfile)

#graph.to_json("./State_Data/VA_Trimmed.json")

graph = Graph.from_json("./State_Data/VA_Trimmed.json")

df = gpd.read_file("./State_Data/VA_Trimmed.shp")

print("loaded data")
#print("nodes",len(graph.nodes()))
#print("edges",len(graph.edges()))


for node in graph.nodes():
    graph.nodes[node]["nBVAP"] = graph.nodes[node]["VAPERSONS"] - graph.nodes[node]["VAPBLACK"]

"""
updater = { "population": updaters.Tally("TAPERSONS", alias="population"),
"cut_edges",cut_edges,
"BVAP":Election("BVAP",{"BVAP":"VAPBLACK","nBVAP":"nBVAP"}),
Beispiel #30
0
    Partition,
    accept,
    constraints,
    updaters,
)
from gerrychain.tree import recursive_tree_part
import numpy as np
from sklearn import manifold
from scipy.stats import pearsonr
from scipy.spatial.distance import squareform
from itertools import combinations, product
import pickle
import wasserplan
from scipy.optimize import linear_sum_assignment

graph = Graph.from_json("./NC_VTDjson.json")
pop_col = "TOTPOP"
updaters1 = {
    "population": updaters.Tally("TOTPOP", alias="population"),
    "cut_edges": cut_edges,
}
total_population = sum([graph.nodes[n][pop_col] for n in graph.nodes()])
initial_partition = Partition(graph, "newplan", updaters1)
ideal_population = sum(
    initial_partition["population"].values()) / len(initial_partition)
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=0.02,