How to connect nodes in a networkx graph? - python

Left is input, right is desired output:
Input: I am given some n. I generate n points uniformly at random from [0, 1]. So, the points are tuples (x, y).
I then add this list of nodes into NetworkX graph object. Now, I'd like to connect the edges as shown in the right. That is, the graph is connected (you can get from anywhere to anywhere using some number of edges) but not necessarily an Erdos Renyi graph.
I'm not sure what the term is for this kind of graph - no overlapping edges graph? but is it possible to generate edges for such a graph using Networkx?

Networks derived from points in Euclidean space are typically called geometric graphs. Graphs with no overlapping edges are called planar graphs. As you have drawn all your edges as straight lines, I assume that you are particularly interested in planar, straight-line graphs (PSLGs).
There are several generators for geometric graphs in networkx, however, I am unsure if any of them would necessarily honor the planarity constraint (it feels that you could coerce the geographical_treshold_graph to do that if you picked the threshold parameter in an intelligent way but I don't have a solution off the top of my head).
Personally, I would start with my random points, and then get the edges by computing a Delaunay triangulation, implemented in scipy.spatial. I would then subsample the edges (depending on the task) and create my graph objects in networkx/igraph/graph-tool.

Related

Drawing a directed graph with NetworkX by overlapping minimum edges

I'm trying to draw a directed graph in python with networkx
It uses Fruchterman-Reingold force-directed algorithm to position nodes. However, I couldn't get a result of graph with minimum overlapping edges. I want something like this in NetworkX or some other python API.
Can Fruchterman-Reingold algorithm produce a graph with minimum overlapping edges? If it can, which parameter should I adjust? If it can not, is there any API or alogrithm to use in python?
My code to visualize
pos = nx.spring_layout(G, k=100, iterations=500, seed=1)
Let me know if you need more info.!
Thanks!

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

Group vertices in clusters using NetworkX

I am trying to represent graphically some graphs, and I need to group in clusters some nodes that have a common characteristics.
I am using NetworkX, and I need to do something similar with the graph from this tutorial, from the slide 44, left figure.
I want to draw some delimiting line around each cluster. My current code is like that:
vec = self.colors
colors = (linspace(0, 1, len(set(vec))) * 20 + 10)
nx.draw_circular(g, node_color=array([colors[x] for x in vec]))
show()
I wish to find an example and see how can I use networkx to cluster the graph.
I'm not positive what your question is. I think you're asking "how do I get networkx to put some nodes close together"
Before I launch into the answer, the drawing documentation for networkx is here: http://networkx.lanl.gov/reference/drawing.html
So that figure you're asking about has 4 different communities that are clustered based on having lots of edges within each community and not many outside.
If you don't want to put much effort into it, spring_layout is often good for putting tightly knit communities together. The basic algorithm of spring_layout acts as if the edges are springs (and nodes repel). So lots of edges keeps nodes close together. Note that it initializes the positions randomly, so each time you'll get a different output.
The easiest way to do this is just
nx.draw_spring(G)
But maybe you want more. If you want to, you can fix every single node's position. Define a dict, usually named pos.
pos = {}
for node in G.nodes_iter():
pos[node] = (xcoord, ycoord).
where xcoord and ycoord are the coordinates you want the node to be at.
Then just do
draw_networkx(G, pos = pos)
That's often a lot of effort. So sometimes you just tell it a few of them have to be in particular places, and let networkx do the rest
Define fixedpos for a few nodes and then run
spring_layout
telling it what nodes are fixed and giving it fixedpos as the initial positions. Then it will hold those fixed and fit everything else around.
Here is some code which generates a network that has 4 completely connected parts and a few other edges between them. (actually it generates a complete network and then deletes all but a few edges between these parts). Then it draws it with a simple spring layout. Then it fixes 4 of them to be at the corners of a square and places the other nodes around those fixed positions.
import networkx as nx
import random
import pylab as py
from math import floor
G = nx.complete_graph(20)
for edge in G.edges():
if floor(edge[0]/5.)!=floor(edge[1]/5.):
if random.random()<0.95:
G.remove_edge(edge[0],edge[1])
nx.draw_spring(G)
py.show()
fixedpos = {1:(0,0), 6:(1,1), 11:(1,0), 16:(0,1)}
pos = nx.spring_layout(G, fixed = fixedpos.keys(), pos = fixedpos)
nx.draw_networkx(G, pos=pos)
py.show()
You can also specify weights to the edges, pass the weights to spring_layout and larger weights will tell it to keep the corresponding nodes closer together. So once you've identified your communities, increase weights within the communities/clusters if necessary to keep them close together.
Note that you can also specify what color to make each node, so it is straightforward to specify the color for each community/cluster.
If you then want to draw curves around each of those clusters, you'll have to do that through matplotlib.

Plot edge by size / length in Igraph 0.6 for Python 2.7 (Not for R)

It appears that I can't find the solution for the following issue:
I want to plot the edges by size (length, not width).
I mean if the edge between V1 and V2 vertices is a value equal to 20 I would like to plot that edge exactly 20 pixels.
If another edges between V2 and V3 is 60 that edge will be longer in the plot.
I can't find how to specify the edge size or length. Maybe it's not possible with a simple codeline like other attributes for plotting (vertex size, colors, width etc)
Igraph tutorials didn't give answer to this. Probably it's difficult.
The shape-orientation of graph is not important even if the fixed edges will give a constant shape I guess.
The graph is undirected but has many vertex and edge sequences.
There is no edge attribute in igraph that would let you control the length of the edge directly. The primary reason is that satisfying all the length constraints exactly is impossible unless your graph has a very sparse structure and/or the lengths are very specific.
The only thing that comes to my mind is a technique called multidimensional scaling (MDS). Without going into the gory details, the input of the MDS is an n x n matrix (where n is the number of vertices in your graph) and the matrix cells contain the desired distances between the points. The output of MDS is an arrangement of the vertices in some lower-dimensional space (typically the 2D plane) where the total squared difference between the actual and the desired distances is minimized. In particular, if the desired distances can be satisfied exactly in the 2D space, MDS will find that configuration for you. igraph includes MDS as a layout algorithm in the layout_mds method of Graph objects.
Now, here comes the catch. I mentioned that the distance matrix is of size n x n. The problem is that this means that you have to prescribe a distance for every vertex pair, not only the connected ones. My impression is that this is not the case in your problem (i.e. you only have distances for the connected vertex pairs), in which case MDS is useless unless you can "approximate" the distances of disconnected vertex pairs somehow - but in this case the layout will also be just an approximation.
Another option is the Kamada-Kawai layout (see Kamada, T. & Kawai, S. (1989). An algorithm for drawing general undirected graphs. Information Processing Letters, 31, 7-15), where edges are modeled as springs, each spring having a prescribed equilibrium length. The layout will try to settle in a configuration that is close to the physical equilibrium (in which case all the spring length are close to their equilibrium length so they exert no force on their endpoints, i.e. the vertices). The problem here is that the Kamada-Kawai layout in igraph is not prepared to handle different equilibrium lengths for the springs, i.e. each link is assumed to have the same "desired" length. If you are willing to implement the Kamada-Kawai layout yourself from scratch in Python, then this could be another possibility.

How to draw same nodes with different edge colours correspond to two different graphs?

Hope my question has not asked before. I have two graphs, which nodes are the same in both of them but edges are different. I want to draw both of graphs in one plot. Which means I have the same nodes, but with two different edge colours. But it gives me two different graphs. How could I have them in one graph but with different edge colours?
If you are using Python, NetworkX and Matplotlib then you can do something like this, where you have two graphs with the same set of nodes and so you draw first the nodes and then the two set of edges in different colors.
import networkx as nx
G=nx.gnm_random_graph(10,20)
G2=nx.gnm_random_graph(10,20)
pos=nx.spring_layout(G)
nx.draw_networkx_nodes(G,pos,node_size=80)
nx.draw_networkx_edges(G,pos,edge_color='r')
nx.draw_networkx_edges(G2,pos,edge_color='b')
Take care with edges of different colors between the same endpoints, they will be indistinguishable.

Categories

Resources