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))
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
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"
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
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"]
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] ###########################
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
# -*- 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)
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")
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()
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)
"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"]
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
############# #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)
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]:
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) ]
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)
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() '''
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"]
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))
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"}),
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,