Skip to main content

A Python package for constructing synthetic geospatial networks

Project description

PySGN: A Python package for constructing synthetic geospatial networks

GitHub CI Read the Docs Codecov PyPI PyPI - License DOI

Introduction

PySGN (Python for Synthetic Geospatial Networks) is a Python package for constructing synthetic geospatial networks. It is built on top of the NetworkX package, which provides a flexible and efficient data structure for representing complex networks and GeoPandas, which extends the datatypes used by pandas to allow spatial operations on geometric types. PySGN is designed to be easy to use and flexible, allowing users to generate networks with a wide range of characteristics.

Installation

PySGN can be installed using pip:

pip install pysgn

If you plan to run the code snippets below or the Getting Started notebook docs/getting_started.ipynb locally, install the optional docs extras to get the other dependencies such as geodatasets, Jupyter and Sphinx:

pip install "pysgn[docs]"

Alternatively, PySGN is available on conda-forge and can be installed with:

conda install -c conda-forge pysgn

To work from source, you may clone this repository:

git clone https://github.com/wang-boyu/pysgn.git
cd pysgn

then either:

  • using pip in editable mode

    pip install -e .
    # or with extras
    pip install -e ".[docs]"
    
  • using conda with the provided environment.yml.

    conda env create -f environment.yml
    conda activate pysgn
    

    This installs PySGN in editable mode (pip install -e .), so no additional installation step is required.

Usage Example

Geospatial Erdős-Rényi Network

Here's a simple example of how to use the geo_erdos_renyi_network function to create a geospatial Erdős-Rényi network. It generates a network where each pair of nodes is connected with probability p, which depends on the spatial distance between the nodes. The parameter a controls the rate of decay of the connection probability with distance.

All PySGN functions expect the input GeoDataFrame to contain a single geometry type (Points or Polygons).

import geodatasets
import geopandas as gpd
from pysgn import geo_erdos_renyi_network

# Load the sample grocery-store points from geodatasets
# and explode the GeoDataFrame into single points (one point per row).
gdf = (
    gpd.read_file(geodatasets.get_path("geoda.groceries"))
    .explode(index_parts=False)
    .reset_index(drop=True)
    .to_crs("EPSG:26971")
)

# Create a geospatial Erdős-Rényi network
graph = geo_erdos_renyi_network(gdf, a=3)

# Output the number of nodes and edges
print(f"Number of nodes: {graph.number_of_nodes()}")
print(f"Number of edges: {graph.number_of_edges()}")

Geospatial Watts-Strogatz Network

Similarly you can use the geo_watts_strogatz_network function to create a geospatial Watts-Strogatz network. It first creates a network where each node is connected to its k nearest neighbors. Then, it rewires each edge with probability p. If an edge is chosen to be rewired, it is replaced with a new edge to a random node, where the probability of connecting to this new node is inversely proportional to the spatial distance.

import geodatasets
import geopandas as gpd
from pysgn import geo_watts_strogatz_network

gdf = (
    gpd.read_file(geodatasets.get_path("geoda.groceries"))
    .explode(index_parts=False)
    .reset_index(drop=True)
    .to_crs("EPSG:26971")
)

# Create a geospatial Watts-Strogatz network
graph = geo_watts_strogatz_network(
    gdf,
    k=4,    # Each node is connected to k nearest neighbors
    p=0.1,  # Probability of rewiring each edge
    a=2,    # Distance decay exponent
)

# Output the number of nodes and edges
print(f"Number of nodes: {graph.number_of_nodes()}")
print(f"Number of edges: {graph.number_of_edges()}")

Geospatial Barabási-Albert Network

You can also use the geo_barabasi_albert_network function to create a geospatial Barabási-Albert network. It creates a network using geospatial preferential attachment, where the probability of connecting to existing nodes depends on both their degrees and the spatial distances.

import geodatasets
import geopandas as gpd
from pysgn import geo_barabasi_albert_network
from pysgn.ordering import density_order

gdf = (
    gpd.read_file(geodatasets.get_path("geoda.groceries"))
    .explode(index_parts=False)
    .reset_index(drop=True)
    .to_crs("EPSG:26971")
)

# Create a geospatial Barabási-Albert network
graph = geo_barabasi_albert_network(
    gdf,
    m=3,                # Each new node connects to 3 existing nodes
    a=2,                # Distance decay exponent
    max_degree=150,     # Maximum degree constraint
    # Use density-based node ordering (nodes in dense areas join first)
    node_order=lambda gdf: density_order(gdf, method='knn'),
)

# Output the number of nodes and edges
print(f"Number of nodes: {graph.number_of_nodes()}")
print(f"Number of edges: {graph.number_of_edges()}")

Export to GeoDataFrames

Once you have a graph, you can convert it back to GeoPandas GeoDataFrames for GIS workflows or file export.

from pysgn import graph_to_gdf

nodes_gdf, edges_gdf = graph_to_gdf(graph)

Documentation

For more information on how to use PySGN, please refer to the documentation.

Contributing

If you run into an issue, please file a ticket for us to discuss. If possible, follow up with a pull request.

If you would like to add a feature, please reach out via ticket or start a discussion. A feature is most likely to be added if you build it!

Don't forget to check out the Contributors guide.

License

PySGN is released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysgn-0.5.1.tar.gz (3.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pysgn-0.5.1-py3-none-any.whl (23.5 kB view details)

Uploaded Python 3

File details

Details for the file pysgn-0.5.1.tar.gz.

File metadata

  • Download URL: pysgn-0.5.1.tar.gz
  • Upload date:
  • Size: 3.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pysgn-0.5.1.tar.gz
Algorithm Hash digest
SHA256 df0ea1bd32ff44b3d2d4e308f16194f81144d4ebe4f45a4ef898ad4aba9982ec
MD5 be809d52b14c1f64f3a170823c2c8386
BLAKE2b-256 fcf2735e96cd1b840f55778c950cbe5456b6d0d9cd8e40474467ad2ff6148680

See more details on using hashes here.

Provenance

The following attestation bundles were made for pysgn-0.5.1.tar.gz:

Publisher: release.yml on wang-boyu/pysgn

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pysgn-0.5.1-py3-none-any.whl.

File metadata

  • Download URL: pysgn-0.5.1-py3-none-any.whl
  • Upload date:
  • Size: 23.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pysgn-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0afb056d2e72e614abc310739c6a7ef2f2adf79ba1626fbb8c149595d6681a26
MD5 6046fd7db8577c89fb78bbfe438e945a
BLAKE2b-256 abd745c98bc6d27c3591520d2583aa3181663d4c2f06969c2fcf98d235f4a64d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pysgn-0.5.1-py3-none-any.whl:

Publisher: release.yml on wang-boyu/pysgn

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page