Skip to content

Graph

Primary graph objects from annnet.core.graph.

The main graph API centers on AnnNet/Graph, bulk vertex and edge construction with add_vertices and add_edges, graph-owned accessors (slices, layers, attrs, views, ops, idx, cache), annotation tables (obs, var, uns), and backend accessors (nx, ig, gt).

AnnNet

annnet.core.graph.AnnNet

Incidence-based graph with slices, multilayer coordinates, and rich edge types.

AnnNet stores topology in a sparse incidence matrix backed by canonical entity and edge registries. A row represents an entity, typically a vertex or an edge-entity, and a column represents an edge. The class supports:

  • binary directed and undirected edges
  • hyperedges, including directed head/tail hyperedges
  • edge-entities that can themselves participate as endpoints
  • slice membership and per-slice edge weights
  • optional multilayer coordinates on vertices and edges
  • dataframe-backed attribute storage

Parameters:

Name Type Description Default
directed bool | None

Default directedness for newly created binary edges. If None, methods fall back to directed semantics unless a per-edge flag is set.

None
v int

Initial row capacity for the incidence matrix.

0
e int

Initial column capacity for the incidence matrix.

0
annotations dict | None

Pre-built annotation tables to use instead of creating empty tables.

None
annotations_backend ('auto', 'polars', 'pandas', 'pyarrow')

Preferred backend for newly initialized annotation tables. "auto" prefers the first installed supported backend.

"auto"
aspects dict[str, list[str]] | None

Initial multilayer aspect declaration. If omitted, the graph starts flat with a single placeholder aspect "_".

None
**kwargs Any

Initial graph-level attributes stored in :attr:graph_attributes.

{}
Notes

Directed incidence columns use positive values for sources or heads and negative values for targets or tails. Undirected binary edges and undirected hyperedges use positive values for all incident entities.

See Also

add_vertex add_edge add_vertices add_edges view

Attributes

num_vertices property
num_vertices

Number of stored vertices.

Returns:

Type Description
int

Same value as :attr:nv.

num_edges property
num_edges

Number of structural edges.

Returns:

Type Description
int

Same value as :attr:ne.

nv property
nv

Number of stored vertices.

Returns:

Type Description
int

Count of entities whose internal kind is "vertex".

ne property
ne

Number of structural edges.

Returns:

Type Description
int

Count of incidence-matrix edge columns.

shape property
shape

Graph shape as (num_vertices, num_edges).

Returns:

Type Description
tuple[int, int]

Vertex and edge counts.

V property
V

All vertices as an immutable tuple.

Returns:

Type Description
tuple[str, ...]

Vertex IDs in graph iteration order.

E property
E

All edges as an immutable tuple.

Returns:

Type Description
tuple[str, ...]

Edge identifiers in graph iteration order.

obs property
obs

Notebook-friendly vertex attribute table.

Returns:

Type Description
DataFrame - like
Notes

This is the quickest way to inspect vertex annotations in a notebook. It returns the underlying vertex-attribute table unchanged.

Examples:

>>> G = AnnNet()
>>> G.add_vertices([{'vertex_id': 'A', 'kind': 'gene'}])
>>> G.obs
>>> G.views.vertices()

Use :attr:obs when you want the raw vertex table directly. Use :attr:views when you want an explicit namespace for materialized tables.

var property
var

Notebook-friendly edge attribute table.

Returns:

Type Description
DataFrame - like
Notes

This is the direct edge-annotation table. It is often the most useful object to display in a notebook after edge insertion or IO.

Examples:

>>> G = AnnNet()
>>> G.add_vertices(['A', 'B'])
>>> G.add_edges([{'source': 'A', 'target': 'B', 'edge_id': 'e1'}])
>>> G.var
>>> G.views.edges()
uns property
uns

Graph-level unstructured metadata.

Returns:

Type Description
dict

Mutable dictionary of graph-level attributes.

attrs property
attrs

Attribute operations namespace.

Returns:

Type Description
AttributesAccessor

Manager for graph-, vertex-, edge-, slice-, and edge-slice annotations.

Notes

Use this namespace for graph-, vertex-, edge-, and slice-level annotations.

Examples:

>>> G.attrs.set_vertex_attrs('A', symbol='TP53')
>>> G.attrs.get_vertex_attrs('A')
>>> G.attrs.set_edge_slice_attrs('baseline', 'e1', weight=0.5)
views property
views

Materialized table namespace.

Returns:

Type Description
ViewsAccessor

Manager for dataframe-style materialized views.

Notes

This is the preferred namespace for notebook inspection and export of graph tables.

Examples:

>>> G.views.vertices()
>>> G.views.edges()
>>> G.views.slices()
>>> G.views.layers()
history instance-attribute
history = HistoryAccessor(self)
ops property
ops

Structural operations namespace.

Returns:

Type Description
OperationsAccessor

Manager for subgraphs, copies, reversals, incidence extraction, and memory inspection.

Examples:

>>> H = G.ops.subgraph(['A', 'B', 'C'])
>>> M = G.ops.vertex_incidence_matrix(sparse=True)
>>> usage = G.ops.memory_usage()
layers property
layers

Layer operations namespace.

Returns:

Type Description
LayerAccessor

Manager for multilayer aspects, layer coordinates, supra matrices, and layer set operations.

Notes

All multilayer configuration and layer-aware analysis lives here.

Examples:

>>> G.layers.set_aspects(['condition'], {'condition': ['ctrl', 'stim']})
>>> G.layers.list_layers()
>>> G.views.layers()
slices property
slices

Slice operations namespace.

Returns:

Type Description
SliceManager

Manager exposing slice creation, membership, set operations, and slice-level analysis.

Examples:

>>> G.slices.add('baseline')
>>> G.slices.active = 'baseline'
>>> G.slices.list()
idx property
idx

Index lookup namespace.

Returns:

Type Description
IndexManager

Manager for entity-to-row and edge-to-column index lookups.

cache property
cache

Sparse matrix cache namespace.

Returns:

Type Description
CacheManager

Manager for derived sparse matrix formats such as CSR and CSC.

nx property
nx

NetworkX interoperability namespace.

Returns:

Type Description
_NXBackendAccessor

Lazy proxy that converts to NetworkX only when an algorithm or backend graph is requested.

Examples:

>>> G.nx.backend()
>>> G.nx.shortest_path(G, 'A', 'B')
ig property
ig

Igraph interoperability namespace.

Returns:

Type Description
_IGBackendAccessor

Lazy proxy that converts to igraph only when requested.

gt property
gt

graph-tool interoperability namespace.

Returns:

Type Description
_GTBackendAccessor

Lazy proxy that converts to graph-tool only when requested.

is_multilayer property
is_multilayer

Whether the graph has declared multilayer aspects.

Returns:

Type Description
bool

True when the graph has user-declared aspects. Flat graphs use the internal sentinel aspect "_" and return False.

Functions

add_vertices
add_vertices(
    vertices, slice=None, layer=None, **attributes
)

Add one vertex or many vertices.

This is the canonical public entry point for vertex creation. Use it for both single-vertex and batch insertion.

Parameters:

Name Type Description Default
vertices str | dict | tuple | Iterable

Vertex specification or iterable of specifications.

Accepted single-vertex forms are:

  • "A"
  • {"vertex_id": "A", "kind": "gene"}
  • {"id": "A", ...}
  • {"name": "A", ...}
  • ("A", {"kind": "gene"})

Accepted batch forms are iterables of the same specifications.

required
slice str

Slice receiving the inserted vertices. If omitted, the active slice is used.

None
layer str | tuple | dict

Layer coordinate for inserted vertices in multilayer graphs. A string is valid only for single-aspect graphs; a tuple must already be in aspect order; a dict maps aspect name to layer value.

None
**attributes Any

Attributes applied to a single vertex. These are merged with attributes in vertices when vertices is a single vertex.

{}

Returns:

Type Description
str | list[str]

The inserted vertex ID for a single vertex, or a list of vertex IDs for batch insertion.

Raises:

Type Description
ValueError

If a dictionary vertex specification does not contain "vertex_id", "id", or "name".

Notes

Vertex attributes are stored in :attr:obs and can be edited through :attr:attrs. In multilayer graphs, omitting layer places the vertex on the placeholder layer coordinate.

Examples:

>>> G = AnnNet()
>>> G.add_vertices('A', kind='gene')
'A'
>>> G.add_vertices(
...     [
...         {'vertex_id': 'B', 'kind': 'protein'},
...         ('C', {'kind': 'metabolite'}),
...     ]
... )
['B', 'C']
add_edges
add_edges(*args, **kwargs)

Add one edge, many edges, or hyperedges.

This is the canonical public entry point for all edge creation. It handles binary edges, directed and undirected edges, edge-entities, and hyperedges through the shape of the input specification.

Parameters:

Name Type Description Default
*args Any

Edge specification. Common forms are:

  • G.add_edges("A", "B")
  • G.add_edges("A", "B", weight=2.0, edge_id="e1")
  • G.add_edges({"source": "A", "target": "B"})
  • G.add_edges([{"source": "A", "target": "B"}, ...])
  • G.add_edges([{"members": ["A", "B", "C"]}, ...])
  • G.add_edges([{"tail": ["A"], "head": ["B", "C"]}, ...])
  • G.add_edges([{"edge_id": "EE1", ...}, ...], as_entity=True)
()
**kwargs Any

Options for single-edge or batch insertion.

{}

Other Parameters:

Name Type Description
source str

Source endpoint for a binary edge.

src str

Source endpoint for a binary edge.

target str

Target endpoint for a binary edge.

tgt str

Target endpoint for a binary edge.

weight float

Incidence weight for the edge.

edge_id str

Explicit edge identifier. If omitted, an edge_N ID is assigned.

directed bool

Directedness for a single edge.

edge_directed bool

Directedness for edge specs in batch input.

slice str

Slice receiving the inserted edges. If omitted, the active slice is used.

as_entity bool

If True, each created edge is also registered as an entity so it can be used as the endpoint of later edges. In batch mode, items that carry no source/target are treated as null-endpoint edge-entity placeholders and require this flag to be set.

parallel ('update', 'error', 'parallel')

Policy for single-edge insertion when edge_id is not supplied and the same endpoints already have an edge. "update" reuses the existing edge; "parallel" creates an additional edge; "error" raises ValueError. Ignored in batch mode.

propagate ('none', 'shared', 'all')

Slice propagation policy. "shared" adds the edge to every slice containing both endpoints; "all" adds it to every slice containing either endpoint.

flexible dict

Data-driven direction policy. Requires keys "var" and "threshold". Single-edge path only.

default_weight float

Batch default for edge specs without an explicit weight.

default_edge_directed bool

Batch default directedness.

default_propagate ('none', 'shared', 'all')

Batch default propagation policy.

default_edge_type str

Batch default edge type stored in the edge record.

default_slice_weight float

Batch per-slice weight override.

Returns:

Type Description
str | list[str]

Edge ID for single-edge insertion, or a list of edge IDs for batch insertion.

Raises:

Type Description
TypeError

If unsupported keyword arguments are supplied for batch insertion.

ValueError

If the edge specification is structurally invalid.

Notes

Hyperedges are detected from dictionaries containing "members" for undirected hyperedges or "head"/"tail" for directed hyperedges. Binary edges use "source"/"target" or "src"/"tgt".

For a full guide covering all input forms, dispatch logic, parallel policy, propagation, flexible direction, and batch formats, see the Adding edges explanation page.

Examples:

>>> G = AnnNet(directed=True)
>>> G.add_vertices(['A', 'B', 'C'])
['A', 'B', 'C']
>>> G.add_edges('A', 'B', edge_id='e1', weight=0.5)
'e1'
>>> G.add_edges(
...     [
...         {'source': 'B', 'target': 'C'},
...         {'members': ['A', 'B', 'C'], 'edge_id': 'h1'},
...     ]
... )
['edge_0', 'h1']
remove_vertices
remove_vertices(vertex_ids, *, errors='raise')

Remove one vertex or many vertices.

Parameters:

Name Type Description Default
vertex_ids str | tuple | Iterable[str | tuple]

Vertex ID, explicit multilayer vertex key, or iterable of IDs/keys.

required
errors ('raise', 'ignore')

"raise" (NetworkX convention) raises KeyError listing the unknown IDs. "ignore" silently skips them.

"raise"

Returns:

Type Description
None
Notes

Incident edges are removed with each vertex.

Examples:

>>> G.remove_vertices('A')
>>> G.remove_vertices(['B', 'C'])
>>> G.remove_vertices('nope', errors='ignore')
remove_edges
remove_edges(edge_ids, *, errors='raise')

Remove one edge or many edges.

Parameters:

Name Type Description Default
edge_ids str | Iterable[str]

Edge ID or iterable of edge IDs to remove.

required
errors ('raise', 'ignore')

"raise" (NetworkX convention) raises KeyError listing the unknown IDs. "ignore" silently skips them.

"raise"

Returns:

Type Description
None

Examples:

>>> G.remove_edges('e1')
>>> G.remove_edges(['e2', 'e3'])
>>> G.remove_edges('nope', errors='ignore')
has_vertex
has_vertex(vertex_id)

Check whether a vertex exists.

Parameters:

Name Type Description Default
vertex_id str | tuple

Bare vertex ID, or explicit (vertex_id, layer_coord) tuple for multilayer graphs.

required

Returns:

Type Description
bool

True if the graph contains a vertex entity matching vertex_id.

Notes

In multilayer graphs, a bare vertex ID returns True if that vertex is present on at least one layer coordinate.

has_edge
has_edge(source=None, target=None, edge_id=None)

Check whether an edge exists.

Parameters:

Name Type Description Default
source str

Source endpoint.

None
target str

Target endpoint.

None
edge_id str

Edge identifier.

None

Returns:

Type Description
bool | tuple[bool, list[str]]

If only edge_id is provided, returns a boolean. If source and target are provided, returns (exists, edge_ids). If all three arguments are provided, returns whether that exact edge ID connects the given endpoints.

Raises:

Type Description
ValueError

If the argument combination is invalid.

Examples:

>>> G.has_edge(edge_id='e1')
True
>>> G.has_edge('A', 'B')
(True, ['e1'])
vertices
vertices()

Return all vertex IDs.

Returns:

Type Description
list[str]

Vertex identifiers, excluding edge-entities.

Notes

In multilayer graphs, the returned IDs are bare vertex IDs. Use G.idx or layer-specific methods when layer coordinates are needed.

edges
edges()

Return all structural edge IDs.

Returns:

Type Description
list[str]

Edge identifiers for edges with an incidence-matrix column.

degree
degree(entity_id)

Return the incidence degree of a vertex or edge-entity.

Parameters:

Name Type Description Default
entity_id str | tuple

Vertex ID, edge-entity ID, or explicit multilayer entity key.

required

Returns:

Type Description
int

Number of non-zero incidence entries in the entity row. Missing entities have degree 0.

incident_edges
incident_edges(vertices, direction='both')

Return edges incident to one or more vertices.

Parameters:

Name Type Description Default
vertices str | Iterable[str]

One vertex identifier or an iterable of identifiers.

required
direction ('in', 'out', 'both')

Directional filter applied to binary edges. Undirected edges are included for both "in" and "out".

"in"

Returns:

Type Description
list[tuple[int, EdgeView]]

Pairs of (column_index, edge_view) as returned by :meth:get_edge, materialized for consistency with the sibling vertices / edges / edge_list APIs which all return lists.

Raises:

Type Description
ValueError

If direction is not "in", "out", or "both".

Examples:

>>> G.incident_edges('A', direction='out')
[(0, EdgeView(edge_id='e0', kind='binary', ...))]
number_of_vertices
number_of_vertices()

Return the number of vertices.

Returns:

Type Description
int

Number of stored vertex entities.

See Also

nv : Property alias for the same count. num_vertices : Descriptive property alias for the same count.

number_of_edges
number_of_edges()

Return the number of edges.

Returns:

Type Description
int

Number of structural edges with incidence columns.

See Also

ne : Property alias for the same count. num_edges : Descriptive property alias for the same count.

read classmethod
read(path, **kwargs)

Read a graph from the native .annnet format.

Parameters:

Name Type Description Default
path str | Path

Input file path.

required
**kwargs

Passed to annnet.io.annnet_format.read.

{}

Returns:

Type Description
AnnNet

Deserialized graph.

Examples:

>>> G = AnnNet.read('graph.annnet')
write
write(path, **kwargs)

Write the graph to the native .annnet format.

Parameters:

Name Type Description Default
path str | Path

Output file path.

required
**kwargs

Passed to annnet.io.annnet_format.write.

{}

Returns:

Type Description
None

Examples:

>>> G.write('graph.annnet')
view
view(
    vertices=None, edges=None, slices=None, predicate=None
)

Create a lazy graph view.

Parameters:

Name Type Description Default
vertices Iterable[str]

Vertex IDs to include.

None
edges Iterable[str]

Edge IDs to include.

None
slices Iterable[str]

Slice IDs to include.

None
predicate callable

Predicate used for additional filtering.

None

Returns:

Type Description
GraphView

View object backed by this graph.

Notes

Views are lightweight filters over an existing graph. Use :attr:views for materialized dataframe views.

global_count
global_count(kind)

Count unique members present across slices.

Parameters:

Name Type Description Default
kind ('vertices', 'edges', 'entities')

Membership domain. "vertices" counts slice vertex members, "edges" counts slice edge members, and "entities" counts the union of both domains.

"vertices"

Returns:

Type Description
int

Number of unique members observed in slice membership.

Raises:

Type Description
ValueError

If kind is not one of "vertices", "edges", or "entities".

Notes

This is a slice-membership count, not a storage count. For graph storage counts, use :attr:num_vertices and :attr:num_edges.

get_vertex
get_vertex(index)

Return the vertex identifier stored at an internal row index.

Parameters:

Name Type Description Default
index int

Incidence-matrix row index.

required

Returns:

Type Description
str

Vertex ID at index.

Raises:

Type Description
KeyError

If index is not a valid entity row.

Notes

This is an index-level lookup. Most user code should use :meth:vertices unless it specifically needs row-index mapping.

get_edge
get_edge(index)

Return an :class:EdgeView for the requested edge.

Parameters:

Name Type Description Default
index int | str

Incidence-matrix column index or edge ID.

required

Returns:

Type Description
EdgeView

A tuple-shaped record. (source, target) tuple unpacking still works for backward compatibility; edge_id, kind, members, weight and directed are also exposed as attributes.

Raises:

Type Description
KeyError

If an edge ID is unknown.

edge_list
edge_list()

Materialize binary edges as endpoint tuples.

Returns:

Type Description
list[tuple[str, str, str, float]]

Tuples of (source, target, edge_id, weight) for binary and vertex-edge records. Hyperedges and endpoint-less placeholders are omitted. The weight reflects the active slice's per-edge override when one is set; otherwise the edge's stored weight.

make_undirected
make_undirected(*, drop_flexible=True, update_default=True)

Convert all existing edges to undirected form in place.

Parameters:

Name Type Description Default
drop_flexible bool

If True, clear flexible-direction policies after rewriting edge incidence signs.

True
update_default bool

If True, set G.directed = False so future edges are undirected unless explicitly overridden.

True

Returns:

Type Description
AnnNet

The modified graph, returned for chaining.

Notes

Directed binary edges are rewritten from signed incidence (+w, -w) to unsigned incidence (+w, +w). Directed hyperedges are converted to undirected hyperedges over the union of their head and tail members.

Examples:

>>> G = AnnNet(directed=True)
>>> G.add_vertices(['A', 'B'])
['A', 'B']
>>> G.add_edges('A', 'B')
'edge_0'
>>> G.make_undirected()
AnnNet(...)
X
X()

Return the sparse incidence matrix.

Returns:

Type Description
dok_matrix

Internal incidence matrix. Rows are entities; columns are structural edges.

Notes

The returned matrix is the live internal DOK matrix. Treat it as read-only unless you are implementing core internals.

EdgeType

annnet.core._records.EdgeType