Python bindings for the Open Graph Drawing Framework (OGDF), built with nanobind.
This is a curated subset of OGDF, not a full wrapper: enough to build graphs, run layout and core graph algorithms, style and draw them, and read/write common graph file formats.
make bootstrap # clone OGDF at the pinned tag and build it from source (once)
uv sync # build the extension
uv run pytest # run the tests
uv build # build a wheelmake build (and make sync) run the bootstrap automatically if OGDF has not been built yet. Use make help for additional targets.
import ogdf
# Build a graph.
g = ogdf.Graph()
ogdf.random_planar_connected_graph(g, 30, 45)
# Attach drawing attributes and run a force-directed layout.
ga = ogdf.GraphAttributes(g)
ogdf.FMMMLayout().call(ga)
# Export to SVG.
ogdf.draw_svg(ga, "graph.svg")Algorithms operate on the same Graph, writing per-node/edge results into an array you pass in:
g = ogdf.Graph()
ogdf.complete_bipartite_graph(g, 3, 4)
assert ogdf.is_bipartite(g)
component = ogdf.NodeArrayInt(g)
n = ogdf.connected_components(g, component) # -> number of components-
Graph model:
Graph,Node,Edge, node/edge iteration. -
Attribute arrays:
NodeArray/EdgeArrayin int, double, and bool. -
Attributes:
GraphAttributeswith coordinates, size, labels, and full styling (colors, shapes, fill patterns, stroke, edge arrows, and bends). -
Layouts:
SugiyamaLayout(layered),FMMMLayout/GEMLayout/SpringEmbedderKK/MultilevelLayout(force-directed),StressMinimization/PivotMDS(stress/MDS),PlanarizationLayout(with optional orthogonal routing),SchnyderLayout/FPPLayout/PlanarStraightLayout/PlanarDrawLayout/MixedModelLayout(planar straight-line and mixed-model),TreeLayout/RadialTreeLayout/BalloonLayout,CircularLayout,LinearLayout(arc diagram),TutteLayout(convex planar), andDominanceLayout/VisibilityLayout(upward, for DAGs). -
Algorithms: connectivity and structure tests (
is_connected,is_biconnected,is_bipartite,is_acyclic,is_planar, ...), node/edge k-connectivity (node_connectivity,edge_connectivity), components, cut vertices and bridges, separation pairs and SPQR-tree summary, topological numbering, shortest paths (dijkstra,bellman_ford,a_star_search), minimum spanning tree, maximum flow, minimum-cost flow, global minimum cut and s-t minimum cut (min_st_cut), matching (bipartite and maximum-weight), node coloring, minimum Steiner tree, planar embedding, maximal planar subgraph, crossing minimization (crossing_number), and edge-insertion routing (insert_edges). -
Generators: classic graphs (complete, bipartite, wheel, cube, grid, Petersen, circulant, k-partite, globe, lattice), graph products (cartesian, tensor, strong, lexicographical), operations (union, complement, suspension), and random models (Erdos-Renyi, regular, planar, triconnected, Watts-Strogatz, preferential attachment, Chung-Lu, Waxman, geometric, series-parallel DAG, hierarchy).
-
File I/O: interchange formats GML, GraphML, DOT, GEXF, GDF, TLP (plus extension-based
read/write), and drawing output as SVG and TikZ.
make demos # writes SVGs and data files to build/demo-output/The demos exercise layouts, styling, algorithm visualizations, generators, and file I/O, and assemble every drawing into build/demo-output/index.html for a side-by-side view. See demos/README.md for details.
make docs # build the MkDocs site into site/
make docs-serve # serve locally with live reloadThe documentation site (docs/) includes a getting-started guide, a coverage checklist of exactly what OGDF functionality is exposed, and a gallery of the demo drawings.
scripts/bootstrap_ogdf.py shallow-clones OGDF at a pinned release tag (foxglove-202510) into thirdparty/ogdf and builds its static libraries from source. The extension then links the OGDF / COIN static libraries, so wheels are self-contained. Because OGDF is prebuilt once (a couple of minutes), rebuilding the bindings only recompiles the binding sources and is fast.
The bootstrap script (scripts/bootstrap_ogdf.py) is cross-platform (Linux, macOS, Windows). The pin can be overridden: python scripts/bootstrap_ogdf.py --tag <tag> or OGDF_TAG=<tag> make bootstrap. In CI, run the bootstrap once per platform (e.g. in cibuildwheel's CIBW_BEFORE_ALL) so OGDF is reused across all Python versions.