This notebook implements a hierarchical, multi-level directed graph modeling class called HierarchicalGraph. It supports rich metadata on both nodes and edges, multi-edge support, clustered + colored visualization, graph merging, selective subgraph viewing, and structured attribute extraction.
| Level | Meaning | Implemented as |
|---|---|---|
| Inner Graph | Detailed node-to-node directed relations (supports parallel edges) | networkx.MultiDiGraph() |
| Outer Graph | Roots-only abstraction (top-level groups). Each inner edge u→v is lifted to root(u)→root(v); edges where root(u)==root(v) are omitted. |
graphviz rendering from the inner graph (no extra parent nodes) |
- Hierarchical containment is defined by the
parentattribute on nodes. - A node with
parent=None(or absent) is a root (top-level group/container). - Inner visualization renders clusters (subgraphs) for parents without drawing extra parent nodes, and edges to/from parents are attached to their clusters (so you don’t get stray grey duplicates).
- You can set
colorper node. If omitted, visualization falls back to white. - You may still pass a palette on construction; apply it as you prefer in normalization (optional).
nodes = [
{'label': 'Group A', 'type': 'system', 'color': 'yellow', 'description': 'Top A'},
{'label': 'A', 'parent': 'Group A', 'type': 'system', 'color': 'yellow'},
{'label': 'B', 'parent': 'Group A', 'type': 'user', 'color': 'lightblue'},
]Required:
labelOptional:parent,type,color,description, and any other attributes (preserved).
edges = [
{'start': 'A', 'end': 'B', 'type': 'control', 'weight': 0.4, 'color': 'blue'}
]Required:
start,endOptional:type,weight,color,description, plus arbitrary extra attributes. Parallel edges (samestart/endbut differenttypeor attrs) are supported.
hg = HierarchicalGraph(nodes, edges)
# Inner view: clustered, hierarchical, multi-edge
hg.visualize_inner_graph_with_clusters()
# Outer view: roots only; edges are lifted to root(u) -> root(v)
hg.visualize_outer_graph()-
Nodes: only root nodes (those without a
parent). -
Edges: every inner edge
u→vis mapped toroot(u)→root(v).- If
root(u) == root(v), the edge is suppressed in the outer view (it’s an internal detail). - Multiple lifted edges between the same roots are allowed (shows parallel cross-group relations).
- If
-
Colors: taken from the root nodes’
colorattribute (fallback: white).
hg1 = HierarchicalGraph(nodes1, edges1)
hg2 = HierarchicalGraph(nodes2, edges2)
hg1.merge(hg2)- Node merging is by
label. - Edge merging distinguishes edges by the triple key
(start, end, type). Matching edges are updated; new ones are appended.
hg.visualize_subgraph(['A', 'C', 'F'])Renders the induced subgraph for the provided labels (silently ignores unknown nodes), with colors inherited when available.
hg.get_node_attributes()
hg.get_edge_attributes()Returns consolidated attributes (implementation-specific helpers).
This class supports exporting and importing node and edge data using CSV files. This is useful for persistence, versioning, sharing, or editing data externally (e.g., in Excel).
hg.export_nodes_to_csv("nodes.csv")
hg.export_edges_to_csv("edges.csv")export_nodes_to_csv(filename)— Saves all current node attributes.export_edges_to_csv(filename)— Saves all edge relationships and attributes.
hg.import_nodes_from_csv("nodes.csv")
hg.import_edges_from_csv("edges.csv")import_nodes_from_csv(filename)— Loads node data, validates/normalizes, rebuilds graphs.import_edges_from_csv(filename)— Loads edge data, validates, rebuilds graphs.
After importing, the internal graphs are automatically rebuilt.
Must include at minimum:
label(required) — Unique node identifierparent(optional) — Parent node label (for hierarchy)- Any other attributes are allowed (e.g.,
color,type,description, etc.)
Must include at minimum:
start(required) — Source node labelend(required) — Target node label- Any other attributes are allowed (e.g.,
type,weight,color,description, etc.)