Ejemplo n.º 1
0
def create_block_group_graph(block_group_config) -> nx.Graph:
    """Build a block group graph."""

    indir = block_group_config.get("directory", "wa-block-groups")
    infile = block_group_config.get("filename", "block-groups.shp")

    draw_shapefile = block_group_config.get("draw_shapefile", False)
    draw_graph = block_group_config.get("draw_graph", False)

    pickle = block_group_config.get("pickle_graph", True)

    reload_graph = block_group_config.get("reload_graph", False)

    if not reload_graph:
        if os.path.exists(
                os.path.join(indir, infile + ".annotated_graph.pickle")):
            return nx.read_gpickle(
                os.path.join(indir, infile + ".annotated_graph.pickle"))
        elif os.path.exists(os.path.join(indir, infile + ".graph.pickle")):
            return nx.read_gpickle(
                os.path.join(indir, infile + ".graph.pickle"))

    G = nx.Graph()

    with cd(indir):
        with fiona.open(infile) as block_groups:
            for shp in tqdm(block_groups,
                            "Reading block groups from shapefile"):
                shape_obj = shape(shp['geometry'])

                vertex_name = shp['properties'].get("GEOID")

                G.add_node(vertex_name, shape=shape_obj)

    # draw the input shapefile
    if draw_shapefile:
        plot_shapes([n[1]['shape'] for n in G.nodes(data=True)])

    _connect_graph(G)

    if draw_graph:
        pos = {
            n[0]: [n[1]['shape'].centroid.x, n[1]['shape'].centroid.y]
            for n in G.nodes(data=True)
        }
        nx.draw_networkx(G, pos=pos)
        plt.show()

    if pickle:
        nx.write_gpickle(G, os.path.join(indir, infile + ".graph.pickle"))

    return G
Ejemplo n.º 2
0
    def export(self):
        with cd('out/chromosome_{}/'.format(self.name)):
            with open('elements.csv') as outfile:
                outfile.write(','.join(['element', 'population', 'component']) + '\n')
                graph = self.chromosome.get_master_graph()
                for vertex in graph:
                    data = graph.nodes[vertex]
                    component_idx = self.chromosome.get_component(vertex)
                    outfile.write(','.join([str(vertex), str(data.get('pop', 0)), str(component_idx)]) + '\n')

            with open('components.csv') as outfile:
                component_scores = self.chromosome.get_component_scores()
                outfile.write(','.join(['component'] + Chromosome.__scores__) + "\n")

                for component in component_scores:
                    scores = component_scores[component]
                    outfile.write(','.join([str(component)] + [str(scores[name]) for name in Chromosome.__scores__]))
                    outfile.write('\n')
Ejemplo n.º 3
0
def plot_shapes(objects, outdir="out/", random_color=False, title="plot"):
    """Plots shapely shapes."""
    fig = plt.figure()
    ax = fig.add_subplot(111)

    # calculate plot bounds
    min_x = min_y = float('inf')
    max_x = max_y = float('-inf')

    for obj in objects:
        color = None
        if isinstance(obj, tuple):
            obj, color = obj

        if not color and random_color:
            color = (random.random(), random.random(), random.random())
            patch = descartes.PolygonPatch(obj, color=color, ec=(0, 0, 0))
        elif color:
            patch = descartes.PolygonPatch(obj, color=color, ec=(0, 0, 0))
        else:
            patch = descartes.PolygonPatch(obj, ec=(0, 0, 0))

        ax.add_patch(patch)

        min_x = min(min_x, obj.bounds[0])
        min_y = min(min_y, obj.bounds[1])
        max_x = max(max_x, obj.bounds[2])
        max_y = max(max_y, obj.bounds[3])

    ax.set_xlim(min_x - (max_x - min_x) * 0.1, max_x + (max_x - min_x) * 0.1)
    ax.set_ylim(min_y - (max_y - min_y) * 0.1, max_y + (max_y - min_y) * 0.1)

    plt.title(title)

    ax.set_aspect(1)

    if outdir:
        with cd(outdir):
            plt.savefig('plot.png')
            os.chmod('plot.png', 0o666)
    else:
        plt.show()
Ejemplo n.º 4
0
def create_graphs(data_dir, configs, districts):
    with cd(data_dir):
        county_graph = shape.create_county_graph(configs.get('county'))
        annotater.initialize_county_graph(configs.get('county'),
                                          configs.get('precinct'),
                                          configs.get('voting_data'),
                                          county_graph)

        block_group_graph = shape.create_block_group_graph(
            configs.get('block_group'))
        annotater.initialize_block_group_graph(configs.get('block_group'),
                                               configs.get('precinct'),
                                               configs.get('voting_data'),
                                               county_graph, block_group_graph)

        print("Finished reading in all graphs. Leaving data directory.")

    county_graph['graph']['districts'] = block_group_graph['graph'][
        'districts'] = districts

    return nx.freeze(county_graph), nx.freeze(block_group_graph)
Ejemplo n.º 5
0
def get_precinct_shapes(precinct_config):
    """Get precincts from file."""
    indir = precinct_config.get("directory", "wa-precincts")
    infile = precinct_config.get("filename", "precincts.shp")

    precinct_shapes = {}

    with cd(indir):
        with fiona.open(infile) as precincts:
            for shp in tqdm(precincts, "Reading precincts from shapefile"):
                precinct_obj = shape(shp['geometry'])
                precinct_data = shp['properties']

                if not precinct_obj.is_valid:
                    plot_shapes([precinct_obj])
                    assert False
                assert precinct_obj.area != 0, precinct_obj.area

                st_code = precinct_data.get('ST_CODE')

                assert st_code not in precinct_shapes
                precinct_shapes[st_code] = (precinct_obj, precinct_data)

    return precinct_shapes
Ejemplo n.º 6
0
def create_county_graph(county_config) -> nx.Graph:
    """Build a county graph."""

    indir = county_config.get("directory", "wa-counties")
    infile = county_config.get("filename", "counties.shp")

    draw_shapefile = county_config.get("draw_shapefile", False)
    draw_graph = county_config.get("draw_graph", False)

    pickle = county_config.get("pickle_graph", True)

    reload_graph = county_config.get("reload_graph", False)

    state_code = county_config.get("state_code", "53")

    if not reload_graph:
        if os.path.exists(
                os.path.join(indir, infile + ".annotated_graph.pickle")):
            return nx.read_gpickle(
                os.path.join(indir, infile + ".annotated_graph.pickle"))
        elif os.path.exists(os.path.join(indir, infile + ".graph.pickle")):
            return nx.read_gpickle(
                os.path.join(indir, infile + ".graph.pickle"))

    G = nx.Graph()
    # map English name (e.g., King County) to GEOID (e.g., 53033)
    name_to_geoid = {}

    with cd(indir):
        with fiona.open(infile) as counties:
            for shp in tqdm(counties, "Reading counties from shapefile"):
                if shp['properties'].get("STATEFP") != state_code:
                    continue
                shape_obj = shape(shp['geometry'])

                # the vertex in the graph is named for the geoid
                # the county name is also stored for data matching
                vertex_name = shp['properties'].get("GEOID")
                county_name = shp['properties'].get("NAME")

                G.add_node(vertex_name, shape=shape_obj)
                name_to_geoid[county_name] = vertex_name

    # draw the input shapefile
    if draw_shapefile:
        plot_shapes([n[1]['shape'] for n in G.nodes(data=True)])

    _connect_graph(G)

    if draw_graph:
        pos = {
            n[0]: [n[1]['shape'].centroid.x, n[1]['shape'].centroid.y]
            for n in G.nodes(data=True)
        }
        nx.draw_networkx(G, pos=pos)
        plt.show()

    G.graph['name_map'] = name_to_geoid

    if pickle:
        nx.write_gpickle(G, os.path.join(indir, infile + ".graph.pickle"))

    return G
Ejemplo n.º 7
0
def create_block_graph(block_config, block_groups: nx.Graph) -> nx.Graph:
    """Using a block group graph as a base, build a block graph."""

    indir = block_config.get("directory", "wa-blocks")
    infile = block_config.get("filename", "blocks.shp")

    draw_shapefile = block_config.get("draw_shapefile", False)
    draw_graph = block_config.get("draw_graph", False)

    pickle = block_config.get("pickle_graph", True)

    reload_graph = block_config.get("reload_graph", False)

    if not reload_graph:
        if os.path.exists(
                os.path.join(indir, infile + ".annotated_graph.pickle")):
            return nx.read_gpickle(
                os.path.join(indir, infile + ".annotated_graph.pickle"))
        elif os.path.exists(os.path.join(indir, infile + ".graph.pickle")):
            return nx.read_gpickle(
                os.path.join(indir, infile + ".graph.pickle"))

    G = nx.Graph()
    # block group --> list of vertices in that block group
    blocks_per_block_group = defaultdict(list)

    with cd(indir):
        with fiona.open(infile) as blocks:
            for shp in tqdm(blocks, "Reading blocks from shapefile"):
                geo_id = shp['properties'].get('GEOID10')
                # name = shp['properties'].get('NAME10', "Block " + str(idx))
                block_obj = shape(shp['geometry'])
                G.add_node(geo_id, shape=block_obj)

                # GEOID of block == GEOID of block group + block ID
                block_group = geo_id[:-3]
                blocks_per_block_group[block_group].append(geo_id)

    if draw_shapefile:
        plot_shapes([n[1]['shape'] for n in G.nodes(data=True)])

    for i in tqdm(block_groups.nodes(), "Building block group subgraphs"):
        _connect_subgraph(G,
                          blocks_per_block_group[i],
                          blocks_per_block_group[i],
                          same=True)

    for i, j in tqdm(block_groups.edges(),
                     "Building cross-block group subgraphs"):
        _connect_subgraph(G, blocks_per_block_group[i],
                          blocks_per_block_group[j])

    if draw_graph:
        pos = {
            n[0]: [n[1]['shape'].centroid.x, n[1]['shape'].centroid.y]
            for n in G.nodes(data=True)
        }
        nx.draw_networkx(G, pos=pos)
        plt.show()

    if pickle:
        nx.write_gpickle(G, os.path.join(indir, infile + ".graph.pickle"))

    return G
Ejemplo n.º 8
0
            "filename": "block-groups.shp",
            "pickle_graph": False,
            "draw_graph": False,
            "draw_shapefile": False,
            "reload_graph": False
        }

        G = shape.create_block_group_graph(block_group_config)

        block_config = {
            "directory": "blocks",
            "filename": "blocks.shp",
            "pickle_graph": False,
            "draw_graph": False,
            "draw_shapefile": False,
            "reload_graph": False
        }

        G2 = shape.create_block_graph(block_config, G)

        self.assertEqual(len(G2), 96**2)
        self.assertTrue(nx.is_isomorphic(G2, nx.grid_graph([96, 96])))


if __name__ == "__main__":
    with cd('/var/local/rohan/test_data/'):
        if not os.path.exists('block-groups/block-groups.shp') \
                or not os.path.exists('blocks/blocks.shp'):
            generate_test_data()
        unittest.main()