I'm tring draw a graph in networkx and at the same time, calculate edge betweenness centrality of every edge, using this to set a different transparency for each edge.
My code looks like this:
G = nx.gnp_random_graph(10,0.5)
options = {
'node_color':'black',
'node_size':1,
'alpha':0.2
}
edge_betweenness_centrality(G)
nx.draw(G,**options)
plt.show()
Where the first line is to generate a random graph with 10 nodes, and the edge_betweenness_centrality(G) calculate edge betweenness of every edge.The output just like this:
the output of edge_betweenness_centrality(G)
And what I want to do is set the transparency of every edge using the above output. I can only set the unity transparency in options just like the above code 'alpha':0.2. So,how do I achieve that?
Can someone help me? I will be very grateful!
Since the alpha value in nx.draw_network_edges can only be a float and not a list or dictionnary (doc here), you will probably have to loop through your edges and draw each edge seperately. You can specify the edge in the edgelist argument and change the alpha value iteratively.
See code below:
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
G = nx.gnp_random_graph(10,0.5)
options = {
'node_color':'black',
'node_size':200
}
cent=nx.edge_betweenness_centrality(G)
node_pos=nx.circular_layout(G) #Any layout will work here, including nx.spring_layout(G)
nx.draw_networkx_nodes(G,pos=node_pos,**options)#draw nodes
[nx.draw_networkx_edges(G,pos=node_pos,edgelist=[key],alpha=np.amin([value*10,1]),width=5) for key,value in cent.items()] #loop through edges and draw them
plt.show()
And the output gives:
Related
I have created a network graph in R using networkD3.
The graph looks so congested.
So i tried to increase the distance between edges. when I pass in some value through linkDistance, the whole shape is distorted and some nodes disappear. I gave some arbitrary value 10 for all the edges.
What am I doing wrong?
The linkDistance looks like to be a value to multiple the distance between nodes. Maybe you should change this to 2 or 3?
For linkDistance you can use javascript functions like:
value <- 1.3
linkDistance=JS('function(d) {', paste('return d.value *', value,';'), '}'))
I have created a graph using networkx. I am drawing the graph using graphviz, specifically with these lines of code:
pos = nx.graphviz_layout(G2, prog='neato', args='-Goverlap=prism')
plt.figure(figsize=(10, 14))
nx.draw(G2, pos, node_size=sizes, alpha=1, nodelist=nodes, node_color=colors, with_labels=True, labels=labelDict, font_size=8)
The graph consists of a "backbone" of a few larger nodes, to which are attached a few hundred smaller nodes.
I have used args='-Goverlap=prism' (in the first line of code above) to space out the graph, but this has created a problem. It matters much more that the larger nodes be spaced out, but, because of how many small nodes there are, some of the larger nodes are ending up crammed together.
My thoughts on a solution are to generate a graph with only the larger nodes to ensure that they are properly spaced, then add the smaller nodes to this graph without changing the layout of the original nodes. I have done some research, and it seems to be somewhat tricky to add new nodes without changing old ones in graphviz. It is possible to "pin" nodes, but I am unsure of how to do this within networkx.
This is what the graph currently looks like:
Your thoughts seem reasonable. The following code generates a graph, assigns an initial position to nodes 1 and 2, then uses nx.spring_layout to assign positions to all of them. I allow for node 2 to move, but node 1 stays fixed.
import networkx as nx
G=nx.path_graph(6)
originalpos = {1:(0,0), 2:(1,0)}
newpos = nx.spring_layout(G, pos=originalpos, fixed=[1])
newpos
> {0: array([-0.39442754, -0.35733777]),
1: array([ 0., 0.]),
2: array([ 0.44050048, 0.3734393 ]),
3: array([ 0.8658906 , 0.80306291]),
4: array([ 1.21367619, 1.27878715]),
5: array([ 1.45676553, 1.72154196])}
For your case you would get the positions for your backbone and then use those nodes as your fixed list.
I am trying to plot a graph from a distance matrix. The code works fine and gives me an image. The image is big but all the nodes are packed together. I want increase the space between the nodes.
I want the nodes to be more apart not enlarged.
I tried Graphviz NEATO, But the problem with it is that it supports only 100 nodes, Since I have 1000 nodes, it was showing 10 clusters of 100 nodes each.
My overall code -
import networkx as nx
import pickle
import matplotlib.pyplot as plt
print "~~~Unpickle."
p_file = open('pickles/names')
Names = pickle.load(p_file)
p_file.close()
p_file = open('pickles/distance')
Dist = pickle.load(p_file)
p_file.close()
G = nx.Graph()
print "~~~Inserting Nodes."
for store in Names:
G.add_node(store)
print "~~~Inserting Edges."
for i in range(601):
for j in range(601):
if Names[i]!=Names[j]:
G.add_edge(Names[i],Names[j],weight=Dist[i][j])
print "~~~Drawing Graph."
nx.draw(G,pos,node_color='#A0CBE2',edge_color='none',width=1, edge_cmap=plt.cm.Blues, with_labels=False)
print "~~~Saving Figure."
plt.savefig("graph.png", dpi=500, facecolor='w', edgecolor='w',orientation='portrait', papertype=None, format=None,transparent=False, bbox_inches=None, pad_inches=0.1)
print "~~~Success!"
Output (edges and labels removed) :
Output of Graphvix NEATO with 600 Nodes -
From figure documentation:
figure(num=None, figsize=(8, 6), dpi=80, facecolor='w', edgecolor='k')
So figure(figsize=(10,10)) creates an 10 inch -by- 10 inch image, which will be 800-by-800 pixels.
If you want to print a large network graph, the easiest way is to increase DPI.
Try something like:
plt.figure(num=None, figsize=(10, 10), dpi=1200). This will produce a large image file.
You can also try printing pdf
plt.savefig("graph.pdf")
Using this option, the final graph is will not be rasterized.
To change the distance between nodes you can make the nodes smaller or change the layout. Changing
the layout is hard to do well.
Try the scale option in layout
for example,
scale = 2
will double distance between all nodes.
So in your example, change the line
nx.draw(G)
to
pos = nx.circular_layout(G, scale=2)
nx.draw(G, pos)
You can also use different layouts see documentation for more details.
I have a graph and here's a part of it (nodes are located at the intersections of edges; the outer rectangle is not part of the graph):
I want to convert its faces into vertices like this:
And then draw edges between the new vertices and discard the original image:
What is the name of this conversion?
Thanks for your patience; it's been a while since I took graph theory.
You can calculate the centroid of each polygon (face) using the coordinates of its old vertices, and use them as the new vertices. By connecting the new vertices the way you show in the third figure, you get a dual graph of the original graph.
I was wondering if someone could help with the following problem.
I have a dozen nodes, each a different sized circle between 0 - 10. I have a distance for each node-pair (e.g. node A and B are 6 from each other, etc.)
Given this data, would it be possible to compute the position of each node on a grid?
The distance could be from the centre or the edge of a node.
Thanks.
If you just want to have a graph to look at, try building a neato file where you specify edge distance. Neato is a layout program that is part of the GraphViz package.
This is quite easy. Your example above would look like this:
graph G {
A -- B [len=6]
}