Skip to main content

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

Note that currently wheels are only available for linux and macos for python versions 3.9-3.14:

pip install hola-graph

or

uv add hola-graph

Building

Requirements:

  • Python 3.9+
  • C++14 compatible compiler
  • CMake 3.18+
# 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.

Metadata

Release files for hola-graph 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hola-graph 0.1.5
File Size Uploaded Provenance
hola_graph-0.1.5.tar.gz 208.5 kB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for hola-graph 0.1.5
File
hola_graph-0.1.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
hola_graph-0.1.5-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details
hola_graph-0.1.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
hola_graph-0.1.5-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
hola_graph-0.1.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
hola_graph-0.1.5-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
hola_graph-0.1.5-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
hola_graph-0.1.5-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
hola_graph-0.1.5-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
hola_graph-0.1.5-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details
hola_graph-0.1.5-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
hola_graph-0.1.5-cp39-cp39-macosx_11_0_arm64.whl CPython 3.9 CPython 3.9 macOS 11.0+ ARM64 Details

Total release size: 24.8 MB

Release files / hola_graph-0.1.5.tar.gz

Download URL hola_graph-0.1.5.tar.gz
Size 208.5 kB
Tags Source
SHA-256 checksum
How to use checksums
235981328a1e0fcfcabdad09fca5428af9b270743f961fd28669c6cf8832840a
BLAKE2b-256 checksum
How to use checksums
84d6652ac0634eb111df59eee2162a87501542365ce2bcca3d715250aed11b2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL hola_graph-0.1.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 2.4 MB
Tags CPython 3.14 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
c786a39ef925ad07f5b328f9237d01073bfbb7bb5e26e7b93e1247f9c4e7c1fd
BLAKE2b-256 checksum
How to use checksums
6b567157d48b8b10722f74b141fdfe220e3c67f52d0b9c180bb5eb786ff497ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp314-cp314-macosx_11_0_arm64.whl

Download URL hola_graph-0.1.5-cp314-cp314-macosx_11_0_arm64.whl
Size 1.7 MB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8daceb44722f2169929627178e83018286bd38cbf83f528dbf8b5c65bf695e79
BLAKE2b-256 checksum
How to use checksums
9667694542a0480efe70fcfd3223cfa9807df7e6b9b053e9a9804b5cbf8e92ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL hola_graph-0.1.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 2.4 MB
Tags CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
0220c4a7da1e54a4d1fbd150c9ce6120ae3dc7cd34b2a49b48bbf6b670d70dbe
BLAKE2b-256 checksum
How to use checksums
64b79cae0bd47a71eb9dfedb4370c65ceab3255372ef8e6b4ba86f383cb06d73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp313-cp313-macosx_11_0_arm64.whl

Download URL hola_graph-0.1.5-cp313-cp313-macosx_11_0_arm64.whl
Size 1.7 MB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
525fdd7f03aa1c008f55688f2a1408e4a8c2b50e81f024c7a3522a3122e043ca
BLAKE2b-256 checksum
How to use checksums
3b3541434f1f0460dec5e350ada6bd2838bdbfc80caa2f4fc74d31d558a97aa4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL hola_graph-0.1.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 2.4 MB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
89a688465301771a4a863c20b5831f1c6b607173d216183c4ab65de3b1bdddd7
BLAKE2b-256 checksum
How to use checksums
fc8ddfb0c6d95836ea5bda3dc4d38f471dd8f06ae4c6ba1c9eff482c70e38d14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp312-cp312-macosx_11_0_arm64.whl

Download URL hola_graph-0.1.5-cp312-cp312-macosx_11_0_arm64.whl
Size 1.7 MB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
228ea5c2bb64d57629d46364b90294f95a26c2d7647f8d572fe7a09c733f78ec
BLAKE2b-256 checksum
How to use checksums
af42b262ec3131061ae2830ca7a366931cb5d66bff24c4b87bc2a955cacdafc0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL hola_graph-0.1.5-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 2.4 MB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
e4d82ea0f9b18bac6b0b219f63e74a3fee4e8cf47aeb6df45d54c8dc1a4fb176
BLAKE2b-256 checksum
How to use checksums
210bfea9b73a9517c4b7eb50484aaa5d22e00b16568d2567780cd283e5ddc522
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp311-cp311-macosx_11_0_arm64.whl

Download URL hola_graph-0.1.5-cp311-cp311-macosx_11_0_arm64.whl
Size 1.7 MB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
e9b3ca21999079a6cdc9900a0c0ae8828be56aa03daa5fbba5d333bd552f242b
BLAKE2b-256 checksum
How to use checksums
b3d0300bae2d767b7153996af93c581c9fc1437016f72e10bcfb4f80fe34d145
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL hola_graph-0.1.5-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 2.4 MB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
25c8ba12a52726e6f3bf3af0fcf7ee8a385f0a5555a856df8665fda694a3a141
BLAKE2b-256 checksum
How to use checksums
f7b34d00ddaa2fad1ec07552cafa7940cdb7048bf96cd2a8d6187f550e050be3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp310-cp310-macosx_11_0_arm64.whl

Download URL hola_graph-0.1.5-cp310-cp310-macosx_11_0_arm64.whl
Size 1.7 MB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
012444a68032ebdde9bab1b30ffb99bd0de87f395ab74f93162ae29192745830
BLAKE2b-256 checksum
How to use checksums
1065a35370ce3bacde68a1070d2af5f3c731ca6ed83304360eac37e324e80e70
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL hola_graph-0.1.5-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 2.4 MB
Tags CPython 3.9 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
34c94a432e4e777c9a95b971c2d5d4e7f4bd261f5e705e08e809b5f8fde67648
BLAKE2b-256 checksum
How to use checksums
6a6b9dd40afff469a3db765de988ee16c401bc573325e71664f1b318baf24653
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / hola_graph-0.1.5-cp39-cp39-macosx_11_0_arm64.whl

Download URL hola_graph-0.1.5-cp39-cp39-macosx_11_0_arm64.whl
Size 1.7 MB
Tags CPython 3.9 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
05d92e6f3e095dde16a04ea851c1a7f0ece5da1ce3ab7686931d24cffe8454df
BLAKE2b-256 checksum
How to use checksums
74b0293757b40271f9d89e1dd0ebad3c8cc76a2207c68199064dcaac3eb8eb38
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Security for hola-graph 0.1.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.5 This release

13 release files No provenance

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