Skip to main content

A pybind11 wrapper to adaptagrams HOLA: Human-like Orthogonal Layout Algorithm.

Project description

hola-graph

A Python wrapper for the HOLA (Human-like Orthogonal Layout Algorithm) from the adaptagrams C++ library. HOLA produces graph layouts that approximate what a human would create - clean, orthogonal, and aesthetically pleasing.

Based on the research paper: HOLA: Human-like Orthogonal Network Layout (Kieffer, Dwyer, Marriott, Wybrow - IEEE TVCG 2016).

Features

  • HOLA Layout Algorithm: Produces human-like orthogonal graph layouts
  • High-Level API: HolaGraph, HolaNode, HolaEdge classes with Pythonic interface
  • Low-Level Bindings: Direct access to C++ classes via hola_graph._core
  • File I/O: Load/save graphs in TGLF format, export to SVG and JSON
  • NetworkX Integration: Convert between hola-graph and NetworkX graphs
  • Matplotlib Visualization: Plot graphs directly with customizable styling
  • Layout Options: Configurable via HolaOpts and ColaOptions classes
  • Geometric Types: Point, Box, Polygon, Rectangle from libavoid

Installation

Requirements

  • Python 3.9+
  • C++14 compatible compiler
  • CMake 3.18+

Building

# Clone the repository
git clone https://github.com/shakfu/hola-graph.git
cd hola-graph

# Build (downloads and compiles adaptagrams automatically)
make
# or
make build

# Run tests to verify installation
make test

Or build directly with uv/pip:

uv build   # Creates wheel and sdist in dist/
pip install .

Quick Start

Basic Usage (High-Level API)

from hola_graph import HolaGraph

# Create a graph
g = HolaGraph()

# Add nodes (width, height) - returns the created node
a = g.add_node(30, 20, label="A")
b = g.add_node(30, 20, label="B")
c = g.add_node(30, 20, label="C")

# Connect nodes
g.connect(a, b)
g.connect(b, c)

# Apply HOLA layout
g.layout()

# Export to SVG
g.to_svg("graph.svg")

# Access node properties
print(f"Node A position: ({a.x}, {a.y})")
print(f"Node A size: {a.width} x {a.height}")

Loading from File

from hola_graph import HolaGraph

# Load, layout, and export
g = HolaGraph.from_tglf("input.tglf")
g.layout()
g.to_svg("output.svg")

# Iterate over nodes and edges
for node in g.nodes:
    print(f"{node.label}: ({node.x}, {node.y})")

for edge in g.edges:
    print(f"Edge {edge.id}: {edge.source} -> {edge.target}")

Low-Level API (Direct C++ Bindings)

For advanced use cases, access the C++ bindings directly:

from hola_graph._core import Graph, Node, Edge, do_hola, HolaOpts

# Create a graph
g = Graph()

# Add nodes (width, height)
n1 = Node.allocate(30, 20)
n2 = Node.allocate(30, 20)
g.add_node(n1)
g.add_node(n2)
g.add_edge(n1, n2)

# Apply layout with options
opts = HolaOpts()
opts.nodePaddingScalar = 1.5
do_hola(g, opts)

# Export
with open("graph.svg", "w") as f:
    f.write(g.to_svg())

NetworkX Integration

import networkx as nx
from hola_graph import utils as pu

# Create from NetworkX graph
nx_graph = nx.karate_club_graph()
g = pu.from_networkx(nx_graph, node_width=25, node_height=25)
pu.apply_hola(g)

# Or get positions for NetworkX visualization
pos = pu.layout_networkx(nx_graph)
nx.draw(nx_graph, pos=pos)

Matplotlib Visualization

from hola_graph import utils as pu
import matplotlib.pyplot as plt

g = pu.load_graph("graph.tglf")
pu.apply_hola(g)

# Display
pu.plot_graph(g, title="My Graph", node_color="lightgreen")
plt.show()

# Or save to file
pu.save_plot(g, "graph.png", dpi=150)

JSON Serialization

from hola_graph import utils as pu

# Export to JSON
json_str = pu.to_json(g)
pu.save_json(g, "graph.json")

# Import from JSON
g = pu.from_json(json_str)
g = pu.load_json("graph.json")

API Reference

High-Level API (hola_graph)

Class Description
HolaGraph Main graph class with Pythonic interface
HolaNode Node with position, size, and label properties
HolaEdge Frozen dataclass representing an edge

HolaGraph Methods

# Construction
g = HolaGraph()                     # Create empty graph
g = HolaGraph.from_tglf(path)       # Load from TGLF file

# Adding nodes and edges
node = g.add_node(w, h)             # Add node, returns HolaNode
node = g.add_node(w, h, label="A")  # Add node with label
g.connect(node1, node2)             # Connect two nodes

# Layout and export
g.layout()                          # Apply HOLA layout
g.layout(opts)                      # Apply with HolaOpts
g.to_svg(path)                      # Export to SVG file
svg_str = g.to_svg()                # Get SVG as string
tglf_str = g.to_tglf()              # Get TGLF as string

# Properties
g.nodes                             # List of HolaNode objects
g.edges                             # List of HolaEdge objects
len(g)                              # Number of nodes

HolaNode Properties

node.id                             # Unique node ID
node.label                          # Node label (auto-generated if not set)
node.x, node.y                      # Center position
node.position                       # (x, y) tuple
node.width, node.height             # Dimensions
node.size                           # (width, height) tuple

HolaEdge Attributes

edge.id                             # Unique edge ID
edge.source                         # Source node ID
edge.target                         # Target node ID

Low-Level API (hola_graph._core)

Class Description
Graph C++ graph container
Node C++ graph vertex
Edge C++ connection between nodes
HolaOpts Configuration for HOLA algorithm
ColaOptions Configuration for constraint-based layout
Function Description
do_hola(graph, opts=None) Apply HOLA layout algorithm
graph_from_tglf_file(path) Load graph from TGLF file

Utility Functions (hola_graph.utils)

# File I/O
load_graph(path)                    # Load from TGLF
save_svg(graph, path)               # Save as SVG
save_tglf(graph, path)              # Save as TGLF
load_json(path) / save_json(g, p)   # JSON I/O

# Graph building
create_node(w, h, x=None, y=None)   # Create validated node
GraphBuilder()                       # Fluent graph construction

# Layout helpers
apply_hola(graph, opts=None)        # Apply layout, return graph
compact_layout_opts()               # Preset for dense layouts
spacious_layout_opts()              # Preset for spread-out layouts
layout_context(graph)               # Context manager for temporary layout

# Analysis
graph_stats(graph)                  # Get statistics dict
print_graph_info(graph)             # Print summary

# NetworkX
to_networkx(graph)                  # Convert to NetworkX
from_networkx(nx_graph)             # Convert from NetworkX
layout_networkx(nx_graph)           # Get HOLA positions for NetworkX

# Visualization
plot_graph(graph, ax=None, ...)     # Plot with matplotlib
save_plot(graph, path, ...)         # Save visualization
plot_comparison(g1, g2, ...)        # Side-by-side comparison

Optional Dependencies

Install with pip for additional features:

pip install networkx    # For NetworkX integration
pip install matplotlib  # For visualization

Or install all optional dependencies:

pip install hola-graph[all]

SWIG Wrapper

The adaptagrams library also provides a comprehensive SWIG-based Python wrapper. If swig is available, build it with:

make swig-python

The extension will be in build/adaptagrams/build.

Credits

HOLA algorithm authors:

Steve Kieffer, Tim Dwyer, Kim Marriott, and Michael Wybrow. HOLA: Human-like Orthogonal Network Layout. IEEE Transactions on Visualization and Computer Graphics, Volume 22, Issue 1, pages 349-358. IEEE, 2016.

This project builds against a fork of adaptagrams with CMake support.

Thanks to Wenzel Jakob for pybind11.

License

MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hola_graph-0.1.4.tar.gz (181.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

hola_graph-0.1.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

hola_graph-0.1.4-cp314-cp314-macosx_11_0_arm64.whl (1.7 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

hola_graph-0.1.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

hola_graph-0.1.4-cp313-cp313-macosx_11_0_arm64.whl (1.7 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

hola_graph-0.1.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

hola_graph-0.1.4-cp312-cp312-macosx_11_0_arm64.whl (1.7 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

hola_graph-0.1.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

hola_graph-0.1.4-cp311-cp311-macosx_11_0_arm64.whl (1.7 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

hola_graph-0.1.4-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

hola_graph-0.1.4-cp310-cp310-macosx_11_0_arm64.whl (1.7 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

hola_graph-0.1.4-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

hola_graph-0.1.4-cp39-cp39-macosx_11_0_arm64.whl (1.7 MB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

File details

Details for the file hola_graph-0.1.4.tar.gz.

File metadata

  • Download URL: hola_graph-0.1.4.tar.gz
  • Upload date:
  • Size: 181.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for hola_graph-0.1.4.tar.gz
Algorithm Hash digest
SHA256 f6876fd0a3621c309fd697a91b27b50a89b2beaddd5e552bc2e9d0bc1cd41b50
MD5 15fb8c11f33f4919e18fecb489538d00
BLAKE2b-256 eec3bb2983c1ed19fd9ac6f40a816e6f9ae73d888284508bb7af890bb91d448d

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 34c66416d861147ef28c59faff59176a157213d1f65a26471fc16d2d293a7bbd
MD5 6f9577ec075a608e6978216af15dcd4a
BLAKE2b-256 b398b5e2e516c5a720b73719db3e52aedeff1bd5a3067c5d277a4b79b46083e7

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e209a6f3dbebcc024b80091340137c9729c1802b38d6de8d8a5c9c636156420c
MD5 005afaf26e6b3e7b34a9cf60bd60c381
BLAKE2b-256 71d98366421d100c29ac4331b42d6b335813f6d271103ca44bff00ec7b4f07a0

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9ba562e0d9b55e41407f08c2d474bf76d85442a6fafb96f28c83ae8e4db876e3
MD5 38c295ea159f0ae0731254087a0d620c
BLAKE2b-256 2067d791fbb3a23e1b70ff63f36725fd7bb2420f439d054b3531b72cc6979521

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 27c4cabe6a25173e9861bad2060c9cc93417fb6ce91ea2c111cb7ea5d56c1dd7
MD5 7d6699103e6b380ad6bbc66bec10dcf8
BLAKE2b-256 48ab4d75dd231978d9765cc4e33f16835d8485a38e56f227f74a2e0737230b2c

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1769021a941f187f266e19502f04673955737c09269f8e6fd8cfdd51440e1287
MD5 63ad71d25c01550350744965cf517988
BLAKE2b-256 21083c17d5a01ed9a9090a1f9ea74cddb7b1854a790b0093115ae92f6c014765

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e20b87f5077247e5d066f7661f9b7642098c2b0b77b30e177dca8d71045c5e8e
MD5 e8aeb2ea62c48b3d03585275a6dea394
BLAKE2b-256 01fcf802998730228d3b4a53f4941e46b280366ab7662d07ef44a7b5e95ddbb1

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 011b2f4b1fb62a83c66193a57b832315b5c4e6965207cfdc3be38695c5c4041b
MD5 2ade82626ea6b0ba2c294d71b7f63a03
BLAKE2b-256 d223f2ac15a6e9fb7125ec85dd49a5e0430a55e4f280d4f3ea982b7df0b787a1

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 547cc82b5566e85b9f987d008a3d8da1937cb5f8fefeca84232b71087b0d443c
MD5 5e51f98022dac1a60d6157fadc1ce193
BLAKE2b-256 f4edb592fa36e9724f72c511880580604eca370fbd17e129983fe8e2951fe7a3

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8aa4cdb2c3aeedcb383e067e4838a0df0f9dc6e5c6071691859638e4b4e7d450
MD5 aa6bc465b612c22b84f4e5180705817a
BLAKE2b-256 b1e934ea954217335f83ed252974b069e99bce18560f42c327302ef31b7b1fee

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 880e4957bf416efb9991ea52d3a8d85c0bf5d00cca6d40e85f33aa1078af1dc0
MD5 a32c531c49ffb695b3173a46be107b77
BLAKE2b-256 10bbb24fe9f7232c57cf7c2218a252580ed324bb4fd2b2b962d5ccfc1648cbb2

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4bda9559cfded817dc82b665ced2f30fec1b28e3be6294e4c576876d6195b116
MD5 1cfed96c56f220f3548baf785c4761b7
BLAKE2b-256 9c15a478730a3c4ff27711ba3eab850e479fdc60b72a67d4e33dbe22da9b441e

See more details on using hashes here.

File details

Details for the file hola_graph-0.1.4-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hola_graph-0.1.4-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4207e40cc9ec87cdc2c4faa65bb49135f596899cdd22969cca8e550c9e2e0703
MD5 8d023065e2f2beb8412c3e6d798b2b49
BLAKE2b-256 670318f81f67b30336a5d8614bbe629804593004aa0c8e0e0358bcc853060f20

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page