def subgraph_view(G, filter_node=no_filter, filter_edge=no_filter): newG = nx.freeze(G.__class__()) newG._NODE_OK = filter_node newG._EDGE_OK = filter_edge # create view by assigning attributes from G newG._graph = G newG.graph = G.graph newG._node = FilterAtlas(G._node, filter_node) if G.is_multigraph(): Adj = FilterMultiAdjacency def reverse_edge(u, v, k): return filter_edge(v, u, k) else: Adj = FilterAdjacency def reverse_edge(u, v): return filter_edge(v, u) if G.is_directed(): newG._succ = Adj(G._succ, filter_node, filter_edge) newG._pred = Adj(G._pred, filter_node, reverse_edge) newG._adj = newG._succ else: newG._adj = Adj(G._adj, filter_node, filter_edge) return newG
def __init__(self, graph, filter_node=no_filter, filter_edge=no_filter): self._graph = graph self._NODE_OK = filter_node self._EDGE_OK = filter_edge # Set graph interface self.graph = graph.graph self._node = FilterAtlas(graph._node, filter_node) self._adj = FilterMultiAdjacency(graph._adj, filter_node, filter_edge)
def __init__(self, graph, filter_node=no_filter, filter_edge=no_filter): self._graph = graph self._NODE_OK = filter_node self._EDGE_OK = filter_edge # Set graph interface self.graph = graph.graph self._node = FilterAtlas(graph._node, filter_node) self._adj = FilterAdjacency(graph._adj, filter_node, filter_edge) self._pred = FilterAdjacency(graph._pred, filter_node, lambda u, v: filter_edge(v, u)) self._succ = self._adj
def __init__(self, graph, filter_node=no_filter, filter_edge=no_filter): self._graph = graph self.root_graph = graph while hasattr(self.root_graph, '_graph'): self.root_graph = self.root_graph._graph self._NODE_OK = filter_node self._EDGE_OK = filter_edge # Set graph interface self.graph = graph.graph self._node = FilterAtlas(graph._node, filter_node) FMA = FilterMultiAdjacency self._adj = FMA(graph._adj, filter_node, filter_edge) self._pred = FMA(graph._pred, filter_node, lambda u, v, k: filter_edge(v, u, k)) self._succ = self._adj
def subgraph_view(G, filter_node=no_filter, filter_edge=no_filter): """View of `G` applying a filter on nodes and edges. `subgraph_view` provides a read-only view of the input graph that excludes nodes and edges based on the outcome of two filter functions `filter_node` and `filter_edge`. The `filter_node` function takes one argument --- the node --- and returns `True` if the node should be included in the subgraph, and `False` if it should not be included. The `filter_edge` function takes two (or three arguments if `G` is a multi-graph) --- the nodes describing an edge, plus the edge-key if parallel edges are possible --- and returns `True` if the edge should be included in the subgraph, and `False` if it should not be included. Both node and edge filter functions are called on graph elements as they are queried, meaning there is no up-front cost to creating the view. Parameters ---------- G : networkx.Graph A directed/undirected graph/multigraph filter_node : callable, optional A function taking a node as input, which returns `True` if the node should appear in the view. filter_edge : callable, optional A function taking as input the two nodes describing an edge (plus the edge-key if `G` is a multi-graph), which returns `True` if the edge should appear in the view. Returns ------- graph : networkx.Graph A read-only graph view of the input graph. Examples -------- >>> G = nx.path_graph(6) Filter functions operate on the node, and return `True` if the node should appear in the view: >>> def filter_node(n1): ... return n1 != 5 ... >>> view = nx.subgraph_view(G, filter_node=filter_node) >>> view.nodes() NodeView((0, 1, 2, 3, 4)) We can use a closure pattern to filter graph elements based on additional data --- for example, filtering on edge data attached to the graph: >>> G[3][4]["cross_me"] = False >>> def filter_edge(n1, n2): ... return G[n1][n2].get("cross_me", True) ... >>> view = nx.subgraph_view(G, filter_edge=filter_edge) >>> view.edges() EdgeView([(0, 1), (1, 2), (2, 3), (4, 5)]) >>> view = nx.subgraph_view(G, filter_node=filter_node, filter_edge=filter_edge,) >>> view.nodes() NodeView((0, 1, 2, 3, 4)) >>> view.edges() EdgeView([(0, 1), (1, 2), (2, 3)]) """ newG = nx.freeze(G.__class__()) newG._NODE_OK = filter_node newG._EDGE_OK = filter_edge # create view by assigning attributes from G newG._graph = G newG.graph = G.graph newG._node = FilterAtlas(G._node, filter_node) if G.is_multigraph(): Adj = FilterMultiAdjacency def reverse_edge(u, v, k=None): return filter_edge(v, u, k) else: Adj = FilterAdjacency def reverse_edge(u, v, k=None): return filter_edge(v, u) if G.is_directed(): newG._succ = Adj(G._succ, filter_node, filter_edge) newG._pred = Adj(G._pred, filter_node, reverse_edge) newG._adj = newG._succ else: newG._adj = Adj(G._adj, filter_node, filter_edge) return newG