Backend accessors¶
AnnNet can remain the source of record while dispatching to installed graph, dataframe, and plotting backends.
In [1]:
Copied!
import annnet as an
import annnet as an
Inspect installed optional components¶
In [2]:
Copied!
print('graph backends:', an.available_backends())
print('dataframe backends:', an.available_dataframe_backends())
print('plot backends:', an.available_plot_backends())
print('selected dataframe backend:', an.select_dataframe_backend('auto'))
print('graph backends:', an.available_backends())
print('dataframe backends:', an.available_dataframe_backends())
print('plot backends:', an.available_plot_backends())
print('selected dataframe backend:', an.select_dataframe_backend('auto'))
graph backends: {'networkx': True, 'igraph': True, 'graph-tool': False, 'pyg': True}
dataframe backends: {'polars': True, 'pandas': True, 'pyarrow': True}
plot backends: {'graphviz': True, 'pydot': False, 'matplotlib': True}
selected dataframe backend: polars
NetworkX and igraph access¶
In [3]:
Copied!
G = an.AnnNet(directed=True)
G.add_vertices(['A', 'B', 'C', 'D'])
G.add_edges('A', 'B', edge_id='e1', weight=1.0)
G.add_edges('A', 'B', edge_id='e1_parallel', weight=0.6)
G.add_edges('B', 'C', edge_id='e2', weight=1.4)
G.add_edges('C', 'D', edge_id='complex_cd', directed=False, weight=0.8)
nx_graph = G.nx.backend()
ig_graph, manifest = an.to_igraph(G)
restored = an.from_igraph(ig_graph, manifest)
print(type(nx_graph).__name__, sorted(nx_graph.nodes()))
print('NetworkX edges:', list(nx_graph.edges(data=True)))
print('igraph:', ig_graph.vcount(), 'vertices,', ig_graph.ecount(), 'edges')
print('igraph edge list:', ig_graph.get_edgelist())
print('round-trip:', restored.shape)
G = an.AnnNet(directed=True)
G.add_vertices(['A', 'B', 'C', 'D'])
G.add_edges('A', 'B', edge_id='e1', weight=1.0)
G.add_edges('A', 'B', edge_id='e1_parallel', weight=0.6)
G.add_edges('B', 'C', edge_id='e2', weight=1.4)
G.add_edges('C', 'D', edge_id='complex_cd', directed=False, weight=0.8)
nx_graph = G.nx.backend()
ig_graph, manifest = an.to_igraph(G)
restored = an.from_igraph(ig_graph, manifest)
print(type(nx_graph).__name__, sorted(nx_graph.nodes()))
print('NetworkX edges:', list(nx_graph.edges(data=True)))
print('igraph:', ig_graph.vcount(), 'vertices,', ig_graph.ecount(), 'edges')
print('igraph edge list:', ig_graph.get_edgelist())
print('round-trip:', restored.shape)
MultiDiGraph ['A', 'B', 'C', 'D']
NetworkX edges: [('A', 'B', {'weight': 1.0}), ('A', 'B', {'weight': 0.6}), ('B', 'C', {'weight': 1.4}), ('C', 'D', {'weight': 0.8}), ('D', 'C', {'weight': 0.8})]
igraph: 4 vertices, 5 edges
igraph edge list: [(3, 1), (3, 1), (1, 0), (0, 2), (2, 0)]
round-trip: (4, 4)
Draw the AnnNet source graph¶
In [4]:
Copied!
from annnet.utils import plotting
plotting.plot(G, backend='graphviz', show_edge_labels=True)
from annnet.utils import plotting
plotting.plot(G, backend='graphviz', show_edge_labels=True)
Out[4]:
Optional backend accessors¶
The same accessor pattern applies to other installed graph backends. AnnNet keeps the annotated graph state and projects it when another library has the algorithm or file format you need.
Backend accessors are execution targets, not replacement graph stores. AnnNet keeps the annotated graph state and projects it when another library has the algorithm or file format you need.