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.1

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.1
File Size Uploaded
spatial_graph-0.1.1.tar.gz 66.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for spatial-graph 0.1.1
File
spatial_graph-0.1.1-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
spatial_graph-0.1.1-cp311-abi3-win32.whl CPython 3.11 abi3 Windows x86-32 Details
spatial_graph-0.1.1-cp311-abi3-musllinux_1_2_x86_64.whl CPython 3.11 abi3 Linux musl 1.2+ x86-64 Details
spatial_graph-0.1.1-cp311-abi3-musllinux_1_2_aarch64.whl CPython 3.11 abi3 Linux musl 1.2+ ARM64 Details
spatial_graph-0.1.1-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.1-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.1-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details
spatial_graph-0.1.1-cp311-abi3-macosx_10_9_x86_64.whl CPython 3.11 abi3 macOS 10.9+ x86-64 Details

Total release size: 78.1 MB

Release files / spatial_graph-0.1.1.tar.gz

Download URL spatial_graph-0.1.1.tar.gz
Size 66.4 kB
Tags Source
SHA-256 checksum
How to use checksums
245fcdfc30c3a4f7bcb37e7d9a40c3293bc257776fd66c803865efd6ca258910
BLAKE2b-256 checksum
How to use checksums
04cf0c9bab25da711685c1dab7d302b18cba596d86f194093d6a9cb21af22e84
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.1-cp311-abi3-win_amd64.whl

Download URL spatial_graph-0.1.1-cp311-abi3-win_amd64.whl
Size 2.5 MB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
13d2609d016778ae2900b7ce42ef890408618104ad56ccf51a2f1dcf91d43038
BLAKE2b-256 checksum
How to use checksums
e21e3ec46d91ad7f3095a6ecdc762b1e509ce3877e2527f20f4bd4e70da81ac3
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.1-cp311-abi3-win32.whl

Download URL spatial_graph-0.1.1-cp311-abi3-win32.whl
Size 2.0 MB
Tags CPython 3.11 Windows x86-32 abi3
SHA-256 checksum
How to use checksums
c93056c1a9972d8120ebd184c0b3a1f9c636c5c28b2428077c83a51400bc0953
BLAKE2b-256 checksum
How to use checksums
052738744b84e4769c6fae8dda13c32c7c9f0e6cf85c3caca6d73d850ec9992e
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.1-cp311-abi3-musllinux_1_2_x86_64.whl

Download URL spatial_graph-0.1.1-cp311-abi3-musllinux_1_2_x86_64.whl
Size 17.1 MB
Tags CPython 3.11 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
004da6070cce068ab77e62a2a805b4b1bdcf221b109b06a771180e648b196a03
BLAKE2b-256 checksum
How to use checksums
44513c9b2ce14fc216bd66a4e06f7cf7c0353a9fb64c7cf7cb7a37b95caddb98
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.1-cp311-abi3-musllinux_1_2_aarch64.whl

Download URL spatial_graph-0.1.1-cp311-abi3-musllinux_1_2_aarch64.whl
Size 16.7 MB
Tags CPython 3.11 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
f3fb3e411e1593353fe69835c8a821eb111a8c40308fc1186b016254c22bee7a
BLAKE2b-256 checksum
How to use checksums
7d0b8a86d7dc30fd90a02b02435125041d0c0eb12ea481861c8435bd803698b4
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.1-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl

Download URL spatial_graph-0.1.1-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
50b5a613e446e6c2c85e9f5a0a474c7f9d6b81e23fadc0e8623ef6486a2cd367
BLAKE2b-256 checksum
How to use checksums
9bfe9b3866239f29c64ed7176ccb7e97503c7a2ac7dc307798e08f08b7a64cbb
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.1-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

Download URL spatial_graph-0.1.1-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Size 17.0 MB
Tags CPython 3.11 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
f4438db5ba9b89de10b76865dbccc76085d3880cdbab8e9c0c485e568aa187d8
BLAKE2b-256 checksum
How to use checksums
6d7bdffdc587fb0033eb9767f3778346fd98f572fcedceeb5534a62c6e0ec892
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.1-cp311-abi3-macosx_11_0_arm64.whl

Download URL spatial_graph-0.1.1-cp311-abi3-macosx_11_0_arm64.whl
Size 2.8 MB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
13b984c6ed945351a1523e125a8ba8ea5d67729e1ce9e67237180cbedc862755
BLAKE2b-256 checksum
How to use checksums
a45643f47e63c1429edb452bb8c3a29c5003ec1b19b03d59fc553134b0712aaf
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.1-cp311-abi3-macosx_10_9_x86_64.whl

Download URL spatial_graph-0.1.1-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
360db825682ee3e53b3fd05197c9ad08b50908c12a08e50f9e5bf6df538f0876
BLAKE2b-256 checksum
How to use checksums
1ffae7810ba7d7044f09ce7925fa7c060fbd90ab2a5314505041cf7fdf6e9572
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

This release

0.1.1 This release

9 release files

0.1.0

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