Grandalf: Graph and Drawing Algorithms Framework

0.8 · maintenance · verified Fri Apr 10

Grandalf is a pure Python package designed for experimenting with graph drawing algorithms. It currently implements two main layouts: the Sugiyama hierarchical layout and a force-driven (energy minimization) approach. Its primary function is to compute node (x,y) coordinates and route edges, providing the structural layout information without performing the actual graphical rendering, which is left to external graphics toolkits. The current version is 0.8, released in January 2023.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a graph, assign initial dimensions to its vertices, and then apply the Sugiyama layout algorithm. After the layout is computed, each `Vertex` object's `view` attribute will be updated with calculated `(x, y)` coordinates, representing its position on the 2D plane. Grandalf only provides these coordinates; actual drawing requires integration with a separate graphics toolkit.

from grandalf.graphs import Vertex, Edge, Graph
from grandalf.layouts import SugiyamaLayout

# Define nodes (vertices)
V = [Vertex(data) for data in range(10)]

# Define edges for a simple graph
X = [(0, 1), (0, 2), (1, 3), (2, 3), (4, 5), (4, 6), (5, 7), (6, 7), (3, 8), (7, 9)]
E = [Edge(V[u], V[v]) for u, v in X]

# Create a graph instance
g = Graph(V, E)

# Assign placeholder dimensions (width, height) to vertices;
# x,y will be set by the layout algorithm.
for v in V:
    v.view = [0, 0, 20, 20] # [x, y, width, height]

# Iterate through graph components (e.g., for Sugiyama, it processes connected components)
for gr in g.sugiyama():
    # Instantiate the Sugiyama layout algorithm for the current component
    lay = SugiyamaLayout(gr)

    # Initialize and run the layout steps
    lay.init_all()
    lay.algo_graph_layered()
    lay.algo_node_coordinatization()
    lay.algo_edge_routing()

    print(f"--- Layout for Graph Component ---")
    for v in gr.V:
        # After layout, v.view[0] and v.view[1] contain the calculated (x, y) coordinates
        print(f"  Vertex {v.data}: (x={v.view[0]}, y={v.view[1]})")

view raw JSON →