networkx: giving a wrong direction for an edge - python

I am trying to read some dataframe to a networkx graph like this:
bipartGraph = nx.Graph()
bipartGraph.add_edge(618254814, 14337833)
bipartGraph.add_edge(618254882, 12087274)
When I display the edges using the bipartGraph.edges() function, I get the below:
[(14337833, 618254814), (618254882, 12087274)]
So, the direction of the first edge is reversed. I am trying to build a bipartite graph from a dataframe which I need to reuse to build an another graph. Is there any specific property of networkx I am missing?

At least in networkx 1.11 if your graph is undirected, an edge that is added as (u,v) may be returned as either (v,u) or (u,v). [I think this may have been changed in version 2.0]. This is because the underlying data structure is a dict, and there is no guarantee that a dict returns values in any particular order: Why items order in a dictionary changed in Python?.
If you really want a direction on your edge, you should make your graph a DiGraph.

Related

networkX.draw() not producing edges

I'm not sure why my network graph doesn't include edges.
I'm creating a network from a pandas dataframe that looks like the following:
I created the network as follows:
G = nx.from_pandas_edgelist(network_df,
edge_attr='weight',
source='Source',
target='Target',
create_using=nx.Graph())
but nx.draw(G) produces a graph without edges.
I tried using nx.DigGraph() but the result is the same.
Any help is greatly appreciated.
That central "blob" in your plot is a lot of nodes connected together which probably do have edges, but they are obscured by the dense mass of nodes. On the periphery there are a few nodes joined together by edges, but due to the plotting algorithm they pairs (or somewhat larger cluster) are again so close together that the nodes are obscured. The isolated nodes are isolated.
It's probably best to try another layout. The default is spring_layout. Here's another that will probably show it better:
pos = nx.circular_layout(G)
nx.draw(G, pos)
As a general rule, networkx was not designed for the purpose of graph visualization. So you may need to look at other tools like graphviz.

Find Subgraphs inside a Connected Component from a NetworkX Graph

I have built a NetworkX Graph containing 50000 Nodes and about 100 Million edges. I have a list of all connected components of this group using nx.connected_components(G) method. This method results in me having clusters of nodes such that each node has a path to reach every other node in that cluster. Now what I want is, in each of these connected components, I want to find subgraphs/sub-clusters such that each of these subgraphs are connected to each other by exactly one edge. Is there a method in NetworkX that I can use directly or any other way in which I can get this done? Sorry I am very new to graph theory so need a little direction.
If I understand you correctly, then for each subgraph, you want to find all graph cuts of size 1, i.e. you want to find all edges, that if taken away partition the graph into two subgraphs. These edges are called bridges and there are efficient algorithms to find them. The implementation in networkx is accessible via networkx.algorithms.bridges.bridges.
What you want is called minimum spanning three. Using networkx you can do it like this:
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()
G.add_edges_from([(1,2), (1,3), (2,3), (4,5), (4,6), (5,6)])
nx.draw(nx.minimum_spanning_tree(G), with_labels=True)
plt.show()
However, I'm a little bit in doubt if networkx is able to perform on so many edges according to this benchmark. I have tested connected components algorithm on igraph, it worked for me as well (and, of course, much faster), so you might also like to look for igraph based solutions.
Result

delete/modify an edge in graphviz

is there any way to delete an existing edge in a graph?
For example, when I draw an edge using
self.g.edge('a', 'b')
where self.g is my digraph, then I do
self.g.edge('a', 'b', _attributes={'arrowhead': 'dot'})
it draws another edge from a->b so now there are 2 edges instead of 1
basically what I'm trying to do is modify the existing edge
it works for nodes, but not edges
I don't think you can delete or modify anything with this library, but you can avoid multiple edges by initializing the graph with Digraph(strict=True) or similar.
The reason it seems to work for nodes is that Graphviz itself replaces an existing node if a new one with the same name is added later.

Testing if a graph is Directed or Undirected Graph from Edgelist file

I have a text document that is an edge list file. I know how to read the file (using Canopy Enthought), but I don't know how to get the information about the graph that I want.
Main question: Is there a way to detect whether this graph (created from the edge list file) is directed or undirected using networkx commands? Or just if it is weighted or unweighed?
I believe that you have to specify the type of the graph before using the edge list file. Because the edge list file is simply composed of tuples containing nodes to be connected without saying how they are connected. Thus, for instance if you create a graph G = nx.Graph(), then if the node pairs in the file are repeated, there will still be one edge between them and the order of the nodes does not matter; ((node1,node2) is equivalent to (node2,node1)). While if you created the graph as G = nx.DiGraph() the order of nodes makes a difference. Also, specifying G = nx.MultiGraph() more than one edge will exist in case of repetition. G = nx.MultiDiGraph() will have a different result when reading the edge list file. So, check the the graph types documentation to know which type you need to have.
To check if the graph is directed you can use
nx.is_directed(G), you can find the documentation here.
To check if the graph is weighted
There is no specific type to say if the graph has weighted edges or not. But a work around can be to check if edges contain an attribute called weight, as mentioned here. It can be done by
'weight' in G[1][2] # Returns true if an attribute called weight exists in the edge connecting nodes 1 and 2.

Fixed position hierarchical output from NetworkX without graphviz?

I'm trying to use Python to plot simple hierarchical tree. I'm using the networkx module. I declared a simple graph
G=networkx.DiGraph()
After adding nodes and edges into G, I tried using
nx.draw(G)
or
nx.draw_networkx(G)
to plot. The output plot hierarchy are all correct, but the position of the nodes appears all random on the graph. Even worse, each time I ran the script, the node position are different.
There is a solution provided in a similar question which requires graphviz package.
pos=nx.graphviz_layout(G,prog='dot')
nx.draw(G,pos,with_labels=False,arrows=False)
Unfortunately I'm not allowed to install graphviz. So I'm seeking alternative solution here.
From graphviz solution, it looks like it's only needed to compute position of the node. Is it correct to say that, as long as I specify a list of coordinates to the draw command, I would be able to plot node at the correct location?
Thanks
UPDATE (15 Apr 2015) Look at my answer here for code that I think will do what you're after.
So networkx doesn't make it particularly easy to use the graphviz layout if you don't have graphviz because it's a better idea to use graphviz's algorithm if you're trying to reproduce graphviz's layout.
But, if you're willing to put in the effort to calculate the position for each node this is straightforward (as you guessed). Create a dict saying where each node's position should be.
pos = {}
for node in G.nodes():
pos[node] = (xcoord,ycoord)
nx.draw(G,pos)
will do it where xcoord and ycoord are the coordinates you want to have.
The various plotting commands are described here

Categories

Resources