neuralqx.graph.core.utils.plotting module

Graph drawing helpers for GraphHandler.

This module provides Matplotlib based visualisation routines for both planar and non planar graphs managed by GraphHandler. The main use cases are

  • quick inspection of the primal directed multigraph, including parallel edges

  • optional overlay of the dual graph, typically the line graph where primal edges become dual vertices

  • 3D rendering of non planar embeddings, where vertices carry explicit Cartesian coordinates

Planar rendering uses NetworkX layout positions, and represents directed edges as curved arrows. Parallel edges between the same ordered pair of vertices are fanned out by assigning a distinct curvature parameter to each edge.

Non planar rendering assumes an explicit embedding \(p_v \in \mathbb{R}^3\) for each vertex \(v\). To improve depth perception, vertices and edges are coloured by their projected depth along the current viewing direction. If \(\hat d\) is the unit vector pointing towards the camera, then the depth of a point \(p\) is computed as

\[z_{\mathrm{view}}(p) = p \cdot \hat d\]

and the resulting scalar values are mapped to colours via a Matplotlib colour map.

These functions are intended for diagnostics and figure generation, and they may update fields on the handler, for example cached layout positions and stored figure handles.

reorder_edges(edges, nx_graph_edges)

Reorder a list of keyed edges to match the order used by a NetworkX multigraph.

This is a convenience helper for keeping a separate edge list aligned with nx_graph.edges(keys=True). Both inputs are expected to contain the same set of keyed edge tuples (u, v, key).

Parameters:
  • edges (list[tuple]) – Edge tuples to be reordered.

  • nx_graph_edges (list[tuple]) – Reference ordering, typically obtained from NetworkX.

Return type:

list[tuple]

Returns:

edges sorted to match the order of nx_graph_edges.

Raises:

KeyError – If an edge in edges does not appear in nx_graph_edges.

draw_graph(handler, max_rad=0.3, arrow_length=0.1, mutation_scale=20)

Draw the primal directed multigraph with curved arrows for parallel edges.

This routine visualises the handler’s planar NetworkX multigraph using 2D positions stored in handler.positions. Nodes are drawn with labels, and each directed edge is drawn as a Matplotlib matplotlib.patches.FancyArrowPatch.

Parallel edges between the same ordered pair (u, v) are fanned out by assigning each key a different arc curvature. If there are \(n\) parallel edges, the curvature values are spread approximately symmetrically in the interval \([-r_{\max}, r_{\max}]\), where \(r_{\max}\) is controlled by max_rad.

The midpoint and a perpendicular offset are computed for each arc in order to place edge labels cleanly. Edge label rendering is currently disabled in this helper, but the label positions are computed and can be enabled by restoring the commented text block.

Parameters:
  • handler (GraphHandler) – GraphHandler instance providing nx_graph, edges, and positions.

  • max_rad (float) – Maximum absolute curvature parameter used when fanning out parallel edges.

  • arrow_length (float) – Reserved for future control of arrow sizing, currently not used.

  • mutation_scale (float) – Scale factor controlling the rendered arrow head size.

Return type:

None

Returns:

None.

draw_nonplanar_graph(handler, node_size=35000, edge_width=5.0, show_labels=True, alpha_nodes=0.9, alpha_edges=0.85, figsize=(12, 9), elev=25, azim=45, cmap_name='viridis', mesh_alpha=0.08, mesh_density=10, return_fig=False, plot=True)

Draw a non planar embedded graph in 3D with depth based colouring.

This routine assumes the handler stores a mapping from integer vertex labels to original 3D coordinates in handler._nonplanar_int2orig_map. The edge list handler.edges is assumed to reference the integer labels, typically in the keyed form (u, v, k).

Depth based colouring is computed from the current view direction defined by the elevation and azimuth angles. A unit view vector \(\hat d\) is constructed, and each vertex at position \(p_v\) is assigned a scalar depth

\[z_{\mathrm{view}}(v) = p_v \cdot \hat d\]

Vertices are coloured by this depth, and edges are coloured by the mean depth of their endpoints. A faint 3D mesh is drawn in the background to provide spatial reference.

If show_labels is True, each vertex is annotated with its integer index. The text colour is chosen adaptively using a luminance heuristic so that labels remain readable against the node face colour.

Parameters:
  • handler (GraphHandler) – GraphHandler instance containing a non planar coordinate map and edge list.

  • node_size (float) – Marker size control for nodes, scaled internally for Matplotlib 3D scatter.

  • edge_width (float) – Line width for edges in the 3D line collection.

  • show_labels (bool) – If True, draw integer vertex labels at each vertex location.

  • alpha_nodes (float) – Opacity applied to node markers.

  • alpha_edges (float) – Opacity applied to edge segments.

  • figsize (tuple) – Figure size passed to Matplotlib.

  • elev (float) – Elevation angle in degrees for the 3D view.

  • azim (float) – Azimuth angle in degrees for the 3D view.

  • cmap_name (str) – Name of the Matplotlib colour map used for depth colouring.

  • mesh_alpha (float) – Opacity of the background mesh surfaces and wireframes.

  • mesh_density (int) – Grid resolution used to draw the background mesh.

  • return_fig (bool) – If True, return the figure object and do not display or close it.

  • plot (bool) – If True, display the plot. If False, close the figure unless return_fig is True.

Return type:

Optional[Figure]

Returns:

The Matplotlib matplotlib.figure.Figure if return_fig is True, otherwise None.

Raises:

ValueError – If the handler does not contain non planar coordinates.