sdnetwork#
Plotting and styling for semi-directed phylogenetic networks (SemiDirectedPhyNetwork).
Plotting#
- phylozoo.viz.sdnetwork.plot_sdnetwork(network: SemiDirectedPhyNetwork, layout: str = 'pz-unrooted', style: SDNetStyle | None = None, ax: Any | None = None, show: bool = False, **layout_kwargs: Any) Any[source]#
Plot a SemiDirectedPhyNetwork.
This is the main public API function for plotting semi-directed networks. It handles layout computation, styling, and rendering using matplotlib.
- Parameters:
network (SemiDirectedPhyNetwork) – The network to plot.
layout (str, optional) – Layout algorithm. PhyloZoo: ‘pz-unrooted’ (tree-of-blobs layout, any network;
daylightandrefineoptions) or ‘pz-radial’ (circular cladogram of the rooted network). NetworkX: ‘spring’, ‘circular’, ‘kamada_kawai’, ‘planar’, ‘random’, ‘shell’, ‘spectral’, ‘spiral’, ‘bipartite’. Graphviz: ‘dot’, ‘neato’, ‘fdp’, ‘sfdp’, ‘twopi’, ‘circo’. By default ‘pz-unrooted’.style (NetworkStyle, optional) – Styling configuration. If None, uses default style. By default None.
ax (matplotlib.axes.Axes, optional) – Existing axes to plot on. If None, creates new figure and axes. By default None.
show (bool, optional) – If True, automatically display the plot using plt.show(). By default False.
**layout_kwargs – Additional parameters for layout computation.
- Returns:
The axes object containing the plot.
- Return type:
- Raises:
PhyloZooLayoutError – If layout algorithm is not supported.
Examples
>>> from phylozoo.core.network.sdnetwork import SemiDirectedPhyNetwork >>> from phylozoo.viz import plot >>> >>> net = SemiDirectedPhyNetwork( ... undirected_edges=[(3, 1), (3, 2), (3, 100)], ... nodes=[(1, {'label': 'A'}), (2, {'label': 'B'}), (100, {'label': 'C'})] ... ) >>> ax = plot(net)
Layouts#
Each function returns a SDNetLayout; the keyword
arguments are the layout parameters accepted by plot().
- phylozoo.viz.sdnetwork.layout.unrooted.compute_pz_unrooted_layout(network: SemiDirectedPhyNetwork, edge_length: float = 1.0, node_spacing: float = 0.7, inner_scale: float = 0.6, start_angle: float = 0.0, refine: int = 50, daylight: int = 0) SDNetLayout[source]#
Compute a tree-of-blobs layout for a SemiDirectedPhyNetwork.
This is a custom PhyloZoo layout algorithm (pz-unrooted). It works for any connected semi-directed network; for trees it reduces to the classic equal-angle drawing of an unrooted tree.
The algorithm:
Decomposes the network into blobs and builds the tree of blobs (one node per blob, one edge per cut edge).
Roots that tree at its centroid and assigns every subtree an angular wedge proportional to the number of leaves it contains (equal-angle).
Draws each non-trivial blob as a polygon: the nodes on the outer face of a planar embedding lie evenly spaced on a circle, in face order, and the remaining nodes are placed at the barycentre of their neighbours (Tutte embedding). Subtrees attached to interior nodes are drawn inside the blob at a reduced scale.
Optionally equalises the “daylight” around every node (
daylightrounds, blobs kept rigid) and relaxes the drawing with iterations of stress majorization (the algorithm behind Graphvizneato), started from the crossing-free drawing of step 3, with every blob edge targetingnode_spacing. This spreads cramped subtrees and keeps blobs evenly sided, and is deterministic.
- Parameters:
network (SemiDirectedPhyNetwork) – The network to layout.
edge_length (float, optional) – Length of cut edges (tree edges between blobs and pendant edges). By default 1.0.
node_spacing (float, optional) – Target distance between consecutive nodes on a blob’s circle. By default 0.7.
inner_scale (float, optional) – Scale factor for subtrees hanging off interior blob nodes, which are drawn inside the blob. By default 0.6.
start_angle (float, optional) – Rotation of the whole drawing, in radians. By default 0.0.
refine (int, optional) – Number of stress-majorization iterations applied to the tree-of-blobs drawing. Use 0 for the raw geometric drawing (blobs as exact polygons). By default 50.
daylight (int, optional) – Number of equal-daylight rounds applied before the stress refinement: around every tree node and around every blob (as a whole), the subtrees hanging off it through cut edges are rotated so that the empty angular gaps between them become equal (blobs stay rigid). Spreads the drawing while keeping every edge length exact (daylight=8 with refine=0 gives the classic SplitsTree-style unrooted drawing). By default 0.
- Returns:
The computed layout. Positions are centred at the origin and scaled to unit range.
- Return type:
- Raises:
PhyloZooLayoutError – If the network is empty or not connected.
Examples
>>> from phylozoo.core.network.sdnetwork import SemiDirectedPhyNetwork >>> from phylozoo.viz.sdnetwork.layout import compute_pz_unrooted_layout >>> >>> net = SemiDirectedPhyNetwork( ... directed_edges=[(5, 4), (6, 4)], ... undirected_edges=[(5, 3), (5, 6), (6, 7), (4, 8), (8, 1), (8, 2)], ... nodes=[(3, {'label': 'C'}), (7, {'label': 'D'}), ... (1, {'label': 'A'}), (2, {'label': 'B'})] ... ) >>> layout = compute_pz_unrooted_layout(net) >>> len(layout.positions) == net.number_of_nodes() True >>> layout.algorithm 'pz-unrooted'
- phylozoo.viz.sdnetwork.layout.radial.compute_pz_radial_layout(network: SemiDirectedPhyNetwork, radius: float = 1.0, start_angle: float = 0.0, angle_direction: str = 'clockwise', root_location: Any = None, **kwargs: Any) SDNetLayout[source]#
Compute a radial (circular cladogram) layout for a SemiDirectedPhyNetwork.
This is a custom PhyloZoo layout algorithm (pz-radial). The network is rooted with
to_d_network()and the rooted network is drawn as a circular cladogram: root at the centre, leaves evenly spaced on the outer circle, radius growing with the depth, reticulate edges as straight chords. The leaf order comes from the hybrid-aware ordering of the layeredpz-cladogramlayout.- Parameters:
network (SemiDirectedPhyNetwork) – The network to layout (any rootable network, not only trees).
radius (float, optional) – Radius of the leaf circle. By default 1.0.
start_angle (float, optional) – Angle of the first leaf, in radians. By default 0.0.
angle_direction (str, optional) – ‘clockwise’ or ‘counterclockwise’. By default ‘clockwise’.
root_location (node or edge, optional) – Where to root the network (a node, or an edge
(u, v, key)), as accepted byto_d_network. None letsto_d_networkchoose. By default None.**kwargs – Ordering options passed on to
compute_pz_cladogram_layout()(trials,seed).
- Returns:
The computed layout.
- Return type:
- Raises:
PhyloZooLayoutError – If network is empty.
PhyloZooValueError – If angle_direction is invalid.
Examples
>>> from phylozoo.core.network.sdnetwork import SemiDirectedPhyNetwork >>> from phylozoo.viz.sdnetwork.layout import compute_pz_radial_layout >>> >>> net = SemiDirectedPhyNetwork( ... undirected_edges=[(3, 1), (3, 2), (3, 100)], ... nodes=[(1, {'label': 'A'}), (2, {'label': 'B'}), (100, {'label': 'C'})] ... ) >>> layout = compute_pz_radial_layout(net) >>> len(layout.positions) 4
- phylozoo.viz.sdnetwork.layout.nx.compute_nx_layout(network: SemiDirectedPhyNetwork, layout: str = 'spring', **kwargs: Any) SDNetLayout[source]#
Compute layout for SemiDirectedPhyNetwork using NetworkX or Graphviz.
- Parameters:
network (SemiDirectedPhyNetwork) – The network to layout.
layout (str, optional) – Layout algorithm name. NetworkX: ‘spring’, ‘circular’, ‘kamada_kawai’, ‘planar’, ‘random’, ‘shell’, ‘spectral’, ‘spiral’, ‘bipartite’. Graphviz (needs pygraphviz): ‘dot’, ‘neato’, ‘fdp’, ‘sfdp’, ‘twopi’, ‘circo’. By default ‘spring’.
**kwargs – Additional parameters passed to the layout algorithm.
- Returns:
The computed layout.
- Return type:
- Raises:
PhyloZooLayoutError – If layout algorithm is not supported, network is empty, or layout computation fails.
PhyloZooImportError – If Graphviz layout is requested but pygraphviz is not installed.
Examples
>>> from phylozoo.core.network.sdnetwork import SemiDirectedPhyNetwork >>> from phylozoo.viz.sdnetwork.layout.nx import compute_nx_layout >>> >>> net = SemiDirectedPhyNetwork( ... undirected_edges=[(3, 1), (3, 2), (3, 100)], ... nodes=[(1, {'label': 'A'}), (2, {'label': 'B'}), (100, {'label': 'C'})] ... ) >>> layout = compute_nx_layout(net, layout='circular') >>> len(layout.positions) 4
- class phylozoo.viz.sdnetwork.layout.base.SDNetLayout(network: SemiDirectedPhyNetwork, positions: dict[T, NodePosition], edge_routes: dict[tuple[T, T, int], EdgeRoute], algorithm: str = 'pz-radial', parameters: dict[str, Any] = <factory>)[source]#
Bases:
MGraphLayout[T]Layout for SemiDirectedPhyNetwork.
This layout class stores the computed positions and routing information for a SemiDirectedPhyNetwork layout. It is the base layout class for all sdnetwork layout algorithms.
Examples
>>> from phylozoo.core.network.sdnetwork import SemiDirectedPhyNetwork >>> from phylozoo.viz.sdnetwork.layout import compute_pz_radial_layout >>> >>> net = SemiDirectedPhyNetwork( ... undirected_edges=[(3, 1), (3, 2), (3, 100)], ... nodes=[(1, {'label': 'A'}), (2, {'label': 'B'}), (100, {'label': 'C'})] ... ) >>> layout = compute_pz_radial_layout(net) >>> len(layout.positions) 4 >>> layout.algorithm 'pz-radial'
- network#
The semi-directed phylogenetic network this layout is for (read-only).
- Type:
- positions#
Node positions mapping node ID to (x, y) coordinates (read-only).
- edge_routes#
Edge routing information mapping (u, v, key) to EdgeRoute (read-only).
Styling#
Styling for SemiDirectedPhyNetwork plots.
This module provides styling configuration for SemiDirectedPhyNetwork visualizations.
- class phylozoo.viz.sdnetwork.style.SDNetStyle(node_color: str = 'white', node_size: float = 80.0, node_edge_color: str = 'black', node_edge_width: float = 1.5, edge_color: str = 'gray', edge_width: float = 2.0, arrow_head_size: float = 18.0, with_labels: bool = True, label_offset: float = 0.01, label_font_size: float = 10.0, label_color: str = 'black', leaf_color: str = '#0a0a0a', hybrid_color: str = '#fcc0bc', leaf_size: float = 100.0, hybrid_edge_color: str = 'red', label_rotation: float | None = None)[source]#
Bases:
MGraphStyleStyling configuration for SemiDirectedPhyNetwork plots.
This class extends MGraphStyle with SemiDirectedPhyNetwork-specific options, including support for leaves, hybrid nodes, and hybrid edges.
Examples
>>> style = SDNetStyle(node_color='blue', leaf_color='green') >>> style.node_color 'blue'
- copy() SDNetStyle[source]#
Create a copy of this style.
- Returns:
A new SDNetStyle instance with the same values.
- Return type:
Examples
>>> style = SDNetStyle(node_color='blue') >>> style2 = style.copy() >>> style2.node_color 'blue'
- phylozoo.viz.sdnetwork.style.default_style() SDNetStyle[source]#
Get the default style configuration for SemiDirectedPhyNetwork.
- Returns:
Default style configuration.
- Return type:
Examples
>>> style = default_style() >>> style.node_color 'white'