Skip to content

Quickstart

This guide walks through the full pipeline in five steps. An interactive version is available in examples/spatial_graph_algorithms_demo.ipynb.

Loading your own data

If you have a real edge list (e.g. from a Slide-tags or Pixelgen experiment), use load_edge_list. It accepts a CSV path or a pandas DataFrame — whichever you already have.

From a CSV file:

from spatial_graph_algorithms import load_edge_list

sg = load_edge_list("my_experiment.csv")          # expects "source" and "target" columns
sg = load_edge_list("edges.csv", source_col="cell_a", target_col="cell_b")  # custom names

From a pandas DataFrame:

import pandas as pd
from spatial_graph_algorithms import load_edge_list

# Node IDs must be integers
df = pd.DataFrame({
    "source": [0, 1, 2],
    "target": [1, 2, 0],
})
sg = load_edge_list(df)

print(sg)
# SpatialGraph(nodes=3, edges=3, has_ground_truth=False, reconstructed=False)
print(sg.has_ground_truth)  # False — no positions, no false-edge labels

Node identifiers must be integers — a ValueError is raised for any other type. If your IDs are strings or other types, convert them first:

df["source"] = df["source"].astype(int)
df["target"] = df["target"].astype(int)

Original IDs are preserved in sg.node_id_map after internal remapping to 0..n-1.

Since there are no ground-truth coordinates, skip straight to reconstruction:

from spatial_graph_algorithms.reconstruct import reconstruct

sg_rec = reconstruct(sg, method="mds", dim=2, seed=42)

1. Simulate a spatial graph

from spatial_graph_algorithms.simulate import generate

sg = generate(
    n=500,           # number of nodes
    dim=2,           # 2D layout
    shape="circle",  # point cloud geometry
    mode="delaunay_corrected",  # connectivity rule (recommended default)
    false_edges_fraction=0.05,  # 5% noise edges
    seed=42,
)

print(f"Nodes: {sg.adjacency_matrix.shape[0]}")
print(f"Edges: {sg.adjacency_matrix.nnz // 2}")
print(f"False edges: {sg.edge_metadata['is_false'].sum()}")

Supported shapes: "circle", "square", "sphere", "cube", "image".
Supported modes: "delaunay_corrected", "knn", "epsilon", "lattice", "distance_decay", "knn_bipartite", "epsilon_bipartite".

2. Visualise the graph

from spatial_graph_algorithms.plot import plot_network, plot_edge_length_histogram

# True edges in grey, false edges in red
fig = plot_network(sg)
fig.savefig("network.png", dpi=150)

# Edge length distribution
fig = plot_edge_length_histogram(sg, bins=40, density=True)

3. Reconstruct coordinates

Both methods use only the edge list — no positions are seen during reconstruction.

from spatial_graph_algorithms.reconstruct import reconstruct

# Fast baseline: shortest-path MDS
sg_mds = reconstruct(sg, method="mds", dim=2, seed=42)

# State-of-the-art: Node2Vec + UMAP
sg_strnd = reconstruct(sg, method="strnd", dim=2, seed=42)

4. Score the reconstruction

from spatial_graph_algorithms.metrics import evaluate

for label, sgr in [("MDS", sg_mds), ("STRND", sg_strnd)]:
    m = evaluate(sgr)
    print(f"{label}: CPD={m['cpd']:.3f}  KNN={m['knn']:.3f}")
Metric Range Good
CPD [0, 1] > 0.9
KNN [0, 1] > 0.6
Distortion* [0, ∞) < 0.5

* Pass compute_distortion=True to evaluate() to compute distortion.

4b. Check topology-only spatial coherence

Spatial coherence is useful before reconstruction when you want to know whether the graph topology still looks like a low-dimensional proximity graph. It does not require ground-truth positions.

from spatial_graph_algorithms.spatial_coherence import score

coh = score(sg, dim=2, plot=True, output_dir="results/spatial_coherence")

print(coh["spectral_score"])
print(coh["spectral_gap"])
print(coh["eigenvalue_contribution_by_rank"])
print(coh["plot_path"])

Higher spectral_score and a larger gap after dimension 2 indicate stronger 2-D spatial structure. Random false edges usually lower the score and flatten the eigenvalue spectrum.

For a complete clean-vs-noisy example, open the interactive notebook: examples/spatial_coherence_false_edges.ipynb.

5. Side-by-side comparison plot

from spatial_graph_algorithms.plot import plot_comparison

fig = plot_comparison(sg_strnd)
fig.savefig("comparison.png", dpi=150)

Nodes are coloured by their angle from the centroid in the original space.
Procrustes alignment is applied before plotting so orientation differences are removed.

One-call pipeline

For a complete run that writes all CSV + PNG artefacts:

from spatial_graph_algorithms.verify import VerifyConfig, run_report

out = run_report(
    simulation_kwargs=dict(
        n=500, shape="circle", mode="delaunay_corrected",
        false_edges_fraction=0.05, seed=42,
    ),
    config=VerifyConfig(
        output_root="results/",
        run_id="my_run",
        reconstruct_methods=["mds", "strnd"],
    ),
)

print("Output directory:", out["run_dir"])
# results/my_run/
#   report.csv
#   reconstruction_quality.csv
#   degree_distribution.csv
#   run_parameters.csv
#   verify_network.png
#   verify_edge_length_histogram.png
#   comparison_mds.png
#   comparison_strnd.png