Example #1
0
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
Example #2
0
    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)
Example #3
0
    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
Example #4
0
    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
Example #5
0
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