def to_undirected(self): """Return an undirected representation of the digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u,v) and (v,u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This is similar to Graph(self) which returns a shallow copy. self.to_undirected() returns a deepcopy of edge, node and graph attributes. """ H=Graph() H.name=self.name H.add_nodes_from(self) H.add_edges_from( (u,v,deepcopy(d)) for u,nbrs in self.adjacency_iter() for v,d in nbrs.iteritems() ) H.graph=deepcopy(self.graph) H.node=deepcopy(self.node) return H
def to_undirected(self, reciprocal=False): """Return an undirected representation of the digraph. Parameters ---------- reciprocal : bool (optional) If True only keep edges that appear in both directions in the original digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u,v) and (v,u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, http://docs.python.org/library/copy.html. Warning ------- If you have subclassed DiGraph to use dict-like objects in the data structure, those changes do not transfer to the Graph created by this method. """ H=Graph() H.name=self.name H.add_nodes_from(self) if reciprocal is True: H.add_edges_from( (u,v,deepcopy(d)) for u,nbrs in self.adjacency_iter() for v,d in nbrs.items() if v in self.pred[u]) else: H.add_edges_from( (u,v,deepcopy(d)) for u,nbrs in self.adjacency_iter() for v,d in nbrs.items() ) H.graph=deepcopy(self.graph) H.node=deepcopy(self.node) return H
def to_undirected(self): H = Graph() H.name = self.name H.add_nodes_from(self) H.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self.adjacency_iter() for v, d in nbrs.iteritems()) H.graph = deepcopy(self.graph) H.node = deepcopy(self.node) return H
def to_undirected(self, reciprocal=False): """Return an undirected representation of the digraph. Parameters ---------- reciprocal : bool (optional) If True only keep edges that appear in both directions in the original digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u, v, data) if either (u, v, data) or (v, u, data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u, v) and (v, u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, http://docs.python.org/library/copy.html. Warning: If you have subclassed DiGraph to use dict-like objects in the data structure, those changes do not transfer to the Graph created by this method. """ H = Graph() H.name = self.name H.add_nodes_from(self) if reciprocal is True: H.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self.adjacency() for v, d in nbrs.items() if v in self._pred[u]) else: H.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self.adjacency() for v, d in nbrs.items()) H.graph = deepcopy(self.graph) H._node = deepcopy(self._node) return H
def add_nodes(): '''Multiple nodes can be added at the same time from any container''' g = Graph([(1, 5), (5, 5)]) # If a kwarg is included, every added node will get the kwarg as an attribute g.add_nodes_from(['a', 'b'], price='$10') print(g.nodes()) # [1, 5, 'a', 'b'] print(g.node['a']) # {'price': '$10'} print(g.node['b']) # {'price': '$10'} # A dictionary can be used as a source of nodes, but the dict values are not incorporated into the graph g.add_nodes_from({'greeting': 'aloha'}) print(g.nodes()) # [1, 5, 'a', 'b', 'greeting'] print(g.node['greeting']) # {}
def to_directed(self, as_view=False): if as_view is True: return nx.graphviews.DiGraphView(self) # deepcopy when not a view from VascGraph.GeomGraph import DiGraph G = DiGraph() G.graph.update(deepcopy(self.graph)) G.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) G.add_edges_from((u, v, deepcopy(data)) for u, nbrs in self._adj.items() for v, data in nbrs.items()) return G
def to_undirected(self): """Return an undirected representation of the digraph. A new graph is returned with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. """ H=Graph() H.name=self.name H.add_nodes_from(self) H.add_edges_from([(v,u,d) for (u,v,d) in self.edges_iter(data=True)]) return H
def to_undirected(self): """Return an undirected representation of the digraph. A new graph is returned with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. """ H = Graph() H.name = self.name H.add_nodes_from(self) H.add_edges_from([(v, u, d) for (u, v, d) in self.edges_iter(data=True)]) return H
def get_nodes_and_data(): ''' The <Graph>.nodes() method accepts an optional kwarg "data" that, regardless of value, is interpreted as a truthy or falsy value - If truthy, a list of 2-tuples is returned. Each 2-tuple consists of (<key>, <attr dict>) - If falsy, a list of keys is returned In v1.11 that's all that happens. It's very simple ''' g = Graph() g.add_nodes_from(['a', 'b'], data='quack') g.add_node('c', data=False) g.add_node('d') print(g.nodes()) # ['a', 'b', 'c', 'd'] print(g.nodes(data=False)) # ['a', 'b', 'c', 'd'] print( g.nodes(data=True) ) # [('a', {'data': 'quack'}), ('b', {'data': 'quack'}), ('c', {'data': False}), ('d', {})] print( g.nodes(data='no') ) # [('a', {'data': 'quack'}), ('b', {'data': 'quack'}), ('c', {'data': False}), ('d', {})]
def create_graph_from_nodes(): ''' The net result is the same as in v1.11: the new graph gets all new nodes that are copies of the original nodes - No edges are copied - No arbitrary attributes are copied ''' g = Graph([(1, 5), (5, 5)]) g.graph['baz'] = 'boo' g.add_node(6) print(g.nodes()) # [1, 5, 6] print(g.edges()) # [(1, 5), (5, 5)] g.nodes[5]['foo'] = 'bar' print(g.nodes[5]) # {'foo': 'bar'} h = Graph() h.add_nodes_from(g) print(h.graph) # {} print(h.nodes()) # [1, 5, 6] print(h.edges()) # {} print(h.nodes[5]) # {}
def create_graph_from_nodes(): ''' - Don't use this strategy alone to copy a graph - None of the arbitrary attributes from nodes, edges, or the graph are copied - If the nodes of a graph object are used to create a new graph object: - No edges are created in the new graph. ''' g = Graph([(1, 5), (5, 5)]) g.graph['baz'] = 'boo' g.add_node(6) print(g.nodes()) # [1, 5, 6] print(g.edges()) # [(1, 5), (5, 5)] g.node[5]['foo'] = 'bar' print(g.node[5]) # {'foo': 'bar'} h = Graph() h.add_nodes_from(g) print(h.graph) # {} print(h.nodes()) # [1, 5, 6] print(h.edges()) # {} print(h.node[5]) # {}
def to_undirected(self): """Return an undirected representation of the digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u,v) and (v,u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, http://docs.python.org/library/copy.html. """ H=Graph() H.name=self.name H.add_nodes_from(self) H.add_edges_from( (u,v,deepcopy(d)) for u,nbrs in self.adjacency_iter() for v,d in nbrs.iteritems() ) H.graph=deepcopy(self.graph) H.node=deepcopy(self.node) return H
def to_undirected(self): """Return an undirected representation of the digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u,v) and (v,u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, http://docs.python.org/library/copy.html. """ H = Graph() H.name = self.name H.add_nodes_from(self) H.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self.adjacency_iter() for v, d in nbrs.items()) H.graph = deepcopy(self.graph) H.node = deepcopy(self.node) return H
def get_nodes_and_data(): ''' <Graph>.nodes() is completely different in v2.4 - The "data" kwarg can do three things: - If data==True, return all node keys and all their data - If data==False, return just a list of node keys - If data==<attribute key>, return all node keys with the attribute key, along with the value of the attribute - In combination with "data", the "default" kwarg will substitute <value> for every node that doesn't have the searched-for attribute key ''' g = Graph() g.add_nodes_from(['a', 'b'], data='quack', size='tiny') g.add_node('c', data=False) g.add_node('d') print(g.nodes()) # ['a', 'b', 'c', 'd'] # Get no node attribute values print(g.nodes(data=False)) # ['a', 'b', 'c', 'd'] # Get all node attribute key-value pairs print(g.nodes(data=True)) # [('a', {'data': 'quack', 'size': 'tiny'}), ('b', {'data': 'quack', 'size': 'tiny'}), ('c', {'data': False}), ('d', {})] # Get all node keys and attribute values for the given attribute key print(g.nodes(data='size')) # [('a', 'tiny'), ('b', 'tiny'), ('c', None), ('d', None)] # Substitute a value for nodes that don't have the key print(g.nodes(data='size', default='purple')) # [('a', 'tiny'), ('b', 'tiny'), ('c', 'purple'), ('d', 'purple')]
def to_undirected(self, reciprocal=False, as_view=False): """Returns an undirected representation of the digraph. Parameters ---------- reciprocal : bool (optional) If True only keep edges that appear in both directions in the original digraph. as_view : bool (optional, default=False) If True return an undirected view of the original directed graph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u, v, data) if either (u, v, data) or (v, u, data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. See Also -------- Graph, copy, add_edge, add_edges_from Notes ----- If edges in both directions (u, v) and (v, u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, https://docs.python.org/2/library/copy.html. Warning: If you have subclassed DiGraph to use dict-like objects in the data structure, those changes do not transfer to the Graph created by this method. Examples -------- >>> G = nx.path_graph(2) # or MultiGraph, etc >>> H = G.to_directed() >>> list(H.edges) [(0, 1), (1, 0)] >>> G2 = H.to_undirected() >>> list(G2.edges) [(0, 1)] """ graph_class = self.to_undirected_class() if as_view is True: return nx.graphviews.generic_graph_view(self, Graph) # deepcopy when not a view G = Graph() G.graph.update(deepcopy(self.graph)) G.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) if reciprocal is True: G.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self._adj.items() for v, d in nbrs.items() if v in self._pred[u]) else: G.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self._adj.items() for v, d in nbrs.items()) return G