Skip to main content

spatial-graph

License PyPI Python Version CI codecov CodSpeed

spatial_graph provides a data structure for directed and undirected graphs, where each node has an nD position (in time or space).

Design Principles

Goals

  • support for arbitrary number of dimensions
  • typed node identifiers and attributes
    • any fixed-length type that is supported by numpy
  • efficient node/edge queries by
    • ROI
    • kNN (by points / lines)
  • numpy-like interface for efficient:
    • graph population and manipulation
    • query results
    • attribute access
  • minimal memory footprint
  • minimal dependencies
    • cython / witty / cheetah3, used only when something has to be compiled at runtime (see Cross-Platform Support)
    • numpy for array interfaces
  • PYX API for graph algorithms in C/C++

Non-Goals

  • graph algorithms
  • I/O
  • non-typed arguments
  • non-spatial graphs
  • out-of-memory support
  • networkx compatibility

Python API

Graph creation:

graph = sg.SpatialGraph(
    ndims=3,
    node_dtype="uint64",
    node_attr_dtypes={"position": "double[3]"},
    edge_attr_dtypes={"score": "float32"},
    position_attr="position",
)

Adding nodes/edges:

graph.add_nodes(
    np.array([1, 2, 3, 4, 5], dtype="uint64"),
    position=np.array(
        [
            [0.1, 0.1, 0.1],
            [0.2, 0.2, 0.2],
            [0.3, 0.3, 0.3],
            [0.4, 0.4, 0.4],
            [0.5, 0.5, 0.5],
        ],
        dtype="double",
    ),
)

graph.add_edges(
    np.array([[1, 2], [3, 4], [5, 1]], dtype="uint64"),
    score=np.array([0.2, 0.3, 0.4], dtype="float32"),
)

Query nodes/edges in ROI:

# nodes/edges will be numpy arrays of dtype uint64 and shape (n,)/(n, 2)
nodes = graph.query_nodes_in_roi(np.array([[0.0, 0.0, 0.0], [0.25, 0.25, 0.25]]))
edges = graph.query_edges_in_roi(np.array([[0.0, 0.0, 0.0], [0.25, 0.25, 0.25]]))

Query nodes/edges by position:

nodes = graph.query_nearest_nodes(np.array([0.3, 0.3, 0.3]), k=3)
edges = graph.query_nearest_edges(np.array([0.3, 0.3, 0.3]), k=3)

Access node/edge attributes:

node_positions = graph.node_attrs[nodes].position
edge_scores = graph.edge_attrs[edges].score

Delete nodes/edges:

graph.remove_nodes(nodes[:1000])

Implementation Details

A SpatialGraph consists of three data structures:

  • The Graph itself, holding nodes, edges, and their attributes (graphlite).
  • Two R-trees for spatial node and edge queries (based on rtree.c). We modified the original code to also include a fast kNN search.

Cross-Platform Support

spatial_graph generates specialized C/C++ for the exact data types you ask for. Where those types can be known in advance we compile them ahead of time and ship them in the wheels; everything else is compiled on your machine the first time it is used, which needs a C compiler.

No compiler needed. The PyPI wheels contain prebuilt PointRTree and LineRTree variants for the common combinations: float32/float64 coordinates, 2 to 5 dimensions, and int64/uint64 items -- as int64[2] / uint64[2] for LineRTree, whose items are node pairs. If your R-tree matches one of those -- as most do -- nothing is compiled, on any supported Python.

Compiler needed. Two cases fall back to compiling at runtime:

  1. Graph, DiGraph, SpatialGraph and SpatialDiGraph. Their node and edge attribute types are only known when you construct the graph, so they cannot be enumerated ahead of time.
  2. R-trees outside the prebuilt set above (an int32 item type, say, or 6 dimensions).

If you or your users need those without a compiler, you can still install spatial_graph from conda-forge, where we include a compiler (clang) in its dependencies.

The wheels are abi3 (stable ABI) and require Python 3.11 or newer, so one wheel per platform covers every supported CPython. Python 3.10 users should pin to a release before this one.

Why can't everything be prebuilt?

There is no cross-platform C/C++ compiler that we can install using pip. numba is maybe the closest to having solved that problem: numba does compile during runtime even if you don't have a compiler locally installed. This works because numba is generating LLVM IR, an intermediate representation language that LLVM can compile into machine code. numba depends on llvmlite, which provides a subset of the LLVM API, statically linked into the binaries in that package. This is just enough to compile the numba generated LLVM IR into machine code. We can't use this strategy, because we compile general C/C++ code. Converting that into LLVM IR is exactly what we need a compiler for.

For Developers

To create a new release, tag the current commit with a version number and push it to the upstream remote:

git tag -a "vX.Y.Z" -m "vX.Y.Z"
git push upstream --follow-tags

This will trigger the CI workflow, which will build the package and upload it to PyPI.

Testing in a conda environment

To simulate a naive user environment, with no assumptions made about the availability of a C/C++ compiler, you can run the included Dockerfile (where the key part of the conda env is the compilers package):

docker build -t spatial_graph .
docker run --rm spatial_graph

Metadata

Release files for spatial-graph 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spatial-graph 0.1.0
File Size Uploaded
spatial_graph-0.1.0.tar.gz 65.9 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for spatial-graph 0.1.0
File
spatial_graph-0.1.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
spatial_graph-0.1.0-cp311-abi3-win32.whl CPython 3.11 abi3 Windows x86-32 Details
spatial_graph-0.1.0-cp311-abi3-musllinux_1_2_x86_64.whl CPython 3.11 abi3 Linux musl 1.2+ x86-64 Details
spatial_graph-0.1.0-cp311-abi3-musllinux_1_2_aarch64.whl CPython 3.11 abi3 Linux musl 1.2+ ARM64 Details
spatial_graph-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 abi3 Linux glibc 2.17+ x86-64, Linux glibc 2.28+ x86-64 Details
spatial_graph-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl CPython 3.11 abi3 Linux glibc 2.17+ ARM64, Linux glibc 2.28+ ARM64 Details
spatial_graph-0.1.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details
spatial_graph-0.1.0-cp311-abi3-macosx_10_9_x86_64.whl CPython 3.11 abi3 macOS 10.9+ x86-64 Details

Total release size: 78.6 MB

Release files / spatial_graph-0.1.0.tar.gz

Download URL spatial_graph-0.1.0.tar.gz
Size 65.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e33240c1c29033854e9895d7fabb0a858ca55f2aa7b6f98cc540677057955141
BLAKE2b-256 checksum
How to use checksums
9dfa0b95970b413060950f568cd8da5eb818a9639ef8d22df63d865363aae86e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / spatial_graph-0.1.0-cp311-abi3-win_amd64.whl

Download URL spatial_graph-0.1.0-cp311-abi3-win_amd64.whl
Size 2.5 MB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
d2409081155ce09066ca44f924fdfde71639a4792a51d0dc585950cc135fff77
BLAKE2b-256 checksum
How to use checksums
28809369cfb19c55b34fe620180499f90406b9af3ba571c8d77c981611942b08
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / spatial_graph-0.1.0-cp311-abi3-win32.whl

Download URL spatial_graph-0.1.0-cp311-abi3-win32.whl
Size 2.1 MB
Tags CPython 3.11 Windows x86-32 abi3
SHA-256 checksum
How to use checksums
ab09fd733f3d7759a08dba33d72b8d4f8d5c703b3ea2f7106f6a72015422d7de
BLAKE2b-256 checksum
How to use checksums
a51d3176a16ce4f0d266c38d2bda00d9a3dd1bed3d0f371aa06746b8bbc92d65
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / spatial_graph-0.1.0-cp311-abi3-musllinux_1_2_x86_64.whl

Download URL spatial_graph-0.1.0-cp311-abi3-musllinux_1_2_x86_64.whl
Size 17.2 MB
Tags CPython 3.11 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
b2324c217d8f057c02262cfc8669987b212fbb0f975359f63535dc2e54377de7
BLAKE2b-256 checksum
How to use checksums
978c07bf39cf71e10bcc764df8ab91604b6778ce5a08cad6eb13b62d494b9ddb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / spatial_graph-0.1.0-cp311-abi3-musllinux_1_2_aarch64.whl

Download URL spatial_graph-0.1.0-cp311-abi3-musllinux_1_2_aarch64.whl
Size 16.8 MB
Tags CPython 3.11 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
6bde562f6e64df2c0aba3021af182b027c3291fe30948d0eb5e6aba2fdbcb8dd
BLAKE2b-256 checksum
How to use checksums
4af342c66773f0edeeb274070e10520e5abde841c2fe4866668610af63e402ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / spatial_graph-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl

Download URL spatial_graph-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Size 17.1 MB
Tags CPython 3.11 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
d1bd5a0729409b972646089f0dada9c71c4a4cbc49ef7c488da3763033d00761
BLAKE2b-256 checksum
How to use checksums
aa89b6542b07f376615c01f8a71306fc9e01946f8c90be866ef1389b078e9f75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / spatial_graph-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

Download URL spatial_graph-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Size 17.1 MB
Tags CPython 3.11 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
3be44218659363f2a8355b96dcadcc6a915413300aba468b624972f2307a9097
BLAKE2b-256 checksum
How to use checksums
715aabf92549cb3b62c07dd454fb71bb8531973cb6c0eb3effb6cf060e7e9785
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / spatial_graph-0.1.0-cp311-abi3-macosx_11_0_arm64.whl

Download URL spatial_graph-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
Size 2.9 MB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
96e30eb466fab2354a6590505d909de3078c88d30d0175132f0543b68f37d090
BLAKE2b-256 checksum
How to use checksums
65e8b64773ce6657822d450a6191621560b4f16d6cbc46bdb308f9a7ec83d27d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / spatial_graph-0.1.0-cp311-abi3-macosx_10_9_x86_64.whl

Download URL spatial_graph-0.1.0-cp311-abi3-macosx_10_9_x86_64.whl
Size 2.8 MB
Tags CPython 3.11 abi3 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
0699b4a63f5c2f0f5f03b4e3d1cc21561c34f094431cc4f694270e6f08370f30
BLAKE2b-256 checksum
How to use checksums
f19a1e9581e5564332ec20eee59f9f64c4c0a5ab47ef070e8f701fc60e6f7c22
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

0.1.1

9 release files

This release

0.1.0 This release

9 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page