Drawing NetworkX graph with Graphviz - networkx

I'm trying to draw a "Spring Layout" type graph.
I'm able to do so with NetworkX but I get quite a messy graph that I'm unable to tidy-up.
I have a 250 branch graph, representing an electric circuit that has a loop and several radial branches.
I've read that it is possible to optimize the node placement by using Graphviz.
Indeed, it seems that NetworkX has linking functions to Graphviz, for example nx.nx_pydot.graphviz_layout(G)
I've tried to use it but I get the following error message:
pos = nx.nx_pydot.graphviz_layout(G) File
"C:\Python27\lib\site-packages\networkx\drawing\nx_pydot.py", line
261, in graphviz_layout
return pydot_layout(G=G, prog=prog, root=root, **kwds) File "C:\Python27\lib\site-packages\networkx\drawing\nx_pydot.py", line
310, in pydot_layout
D_bytes = P.create_dot(prog=prog) File "C:\Python27\lib\site-packages\pydot.py", line 1734, in new_method
format=f, prog=prog, encoding=encoding) File "C:\Python27\lib\site-packages\pydot.py", line 1933, in create
raise OSError(*args) OSError: [Errno 2] "neato" not found in path.
I've duly installed both libraries and included them in my Python code by typing:
import networkx as nx
import graphviz as gv
Am I supposed to install any other library to make it work?
Any help will be wellcome.
Thanks.
Eneko.

The issue was solved by adding import pydot and setting the node position with pos = nx.nx_pydot.graphviz_layout(G,prog,root)
Indeed, it works either way with the following pos = nx.nx_pydot.pydot_layout(G)
Finally, my code looks like the following:
G = nx.Graph()
G.add_weighted_edges_from(BranchList)
prog='neato'
root=None
# pos = nx.nx_pydot.graphviz_layout(G,prog,root)
pos = nx.nx_pydot.pydot_layout(G)
plt.figure()
nx.draw(G,pos,edge_color='black',width=1,linewidths=1, node_size=10,node_color='blue',alpha=0.9)
plt.axis('on')
plt.show()
Note that I keep one of the two possible node positioning pos= solutions as a commented row.
Cheers.
Eneko

Related

How to Highlight any given path in pyvis network graph visualization?

I'm working on a project in which first i had to detect the shortest path in a huge network graph using a-star algorithm followed by visualizing the same graph using pyvis network. However in this pyvis network the path that I've calculated should be highlighted as shortest path.
eg: consider this code for game of thrones character network
from pyvis.network import Network
import pandas as pd
got_net = Network(height='750px', width='100%', bgcolor='#222222', font_color='white')
# set the physics layout of the network
got_net.barnes_hut()
got_data = pd.read_csv('https://www.macalester.edu/~abeverid/data/stormofswords.csv')
sources = got_data['Source']
targets = got_data['Target']
weights = got_data['Weight']
edge_data = zip(sources, targets, weights)
for e in edge_data:
src = e[0]
dst = e[1]
w = e[2]
got_net.add_node(src, src, title=src)
got_net.add_node(dst, dst, title=dst)
got_net.add_edge(src, dst, value=w)
neighbor_map = got_net.get_adj_list()
# add neighbor data to node hover data
for node in got_net.nodes:
node['title'] += ' Neighbors:<br>' + '<br>'.join(neighbor_map[node['id']])
node['value'] = len(neighbor_map[node['id']])
got_net.show('gameofthrones.html')
Now how do i highlight a specific path in this graph? i've gone through the documentation but there isn't anything similar
Here's an example using NetworkX to create the graph and gravis to visualize it. I had to use a different URL, hope it's the same data. I've used the weight as edge widths and colored some with large weights. Alternatively you can calculate a shortest path between two nodes of interest and then color that path or assign edge widths so it stands out.
Disclosure: I'm the author of gravis. I don't know if the same can be achieved with pyvis, but since I know that gravis supports the requirements well, I provided this solution and hope it's useful.
import gravis as gv
import networkx as nx
import pandas as pd
url = 'https://raw.githubusercontent.com/pupimvictor/NetworkOfThrones/master/stormofswords.csv'
got_data = pd.read_csv(url)
g = nx.Graph()
for i, (source, target, weight) in got_data.iterrows():
width = weight/10
g.add_edge(source, target, size=width, color='blue' if width > 3 else 'black')
gv.d3(g)
Edit: Here's the output if you use this code inside a Jupyter notebook. You can also use a regular Python interpreter and display the plot inside a browser window that pops up with fig = gv.d3(g) followed by fig.display().

how to create graph by edge and vertex txt file?

edge : vertex[coordinate]--vertex[coordinate]
how to feed the vertex and edge to a graph? I have tried by myself, but have problems.
import string
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph() # 建立一个空的无向图G
with open("HLN-12-1vertices.txt") as node_list:
for eachline in node_list:
G.add_node()
with open("HLN-12-1edges.txt") as edge_list:
for eachline in edge_list:
G.add_node()
print("number of edges:", G.number_of_edges()) # 输出边的数量
nx.draw(G)
plt.show()
First, you aren't actually passing the node name to the G.add_node parameter. If each line in your vertices text file has the name of the node, you can pass the variable eachline to the function (you might have to parse the file for end of line characters and other parsing if the file is formatted differently.
When you're reading the edges text file, the code again doesn't pass the edge data to the function, and you since you're passing the edge information, you need to use the function G.add_edge() instead. This function takes the parameters 'u_of_edge' and 'v_of_edge' which are the two endpoints of the edge.
Lastly, the function G.add_edge already adds new vertices to the graph if they aren't already created, so if all your vertices have an edge in the edges text file you can skip reading from the vertices text file.

In MatLab, how to adjust the line width drawn by the function 'gplot'?

As the help document of Matlab saying, we can use gplot in such a form as
gplot(A,Coordinates,LineSpec)
But when I try to modify the linewidth of the line and use a code like
gplot(A,Coordinates,'linewidth',2)
an error occurred and the error information saying that Error using gplot:
Too many input arguments.
I was wondering if their is anything wrong with my code.
Building on the answer of PearsonArtPhoto, the lines can be modified if they are explicitly found using findall(gcf,'type','line').
This is a working example:
k = 1:30;
[B,XY] = bucky;
gplot(B(k,k),XY(k,:),'-*')
set(findall(gcf,'type','line'),'LineWidth',5)
axis square
which produces the following figure
You could always do it manually. Try doing this right after plotting your figure.
set(gco,'LineWidth',2)

Python networkx graph: Do not draw old graph together with new graph

The below is my code:
import networkx as nx
for i in range(2):
G = nx.DiGraph()
if i==0:
G.add_edge("A", "B")
elif i==1:
G.add_edge("A", "C")
import matplotlib.pyplot as plt
nx.draw(G)
plt.savefig(str(i)+".png")
G.clear()
It should draw line AB in file 0.png and draw line AC in file 1.png. But, after I ran it. In 0.png, there is one line AB, but in 1.png, there are two lines: AB and AC. It seems that the memory for 0.png is not cleaned, although I have had "G.clear()".
Does anybody know how to fix it?
I have got the solution.
Add plt.clf() after plt.savefig(str(i) + ".png"). It can clean the old graph in pyplot. I hope it can help someone.

Networkx: Importing graph with node values and edges information

I am generating random Geometric graph using networkx. I am exporting all the node and edges information into file.
I want to generate the same graph by importing all the node and edges information from file.
Code to export the node values and edge information.
G=nx.random_geometric_graph(10,0.5)
filename = "ipRandomGrid.txt"
fh=open(filename,'wb')
nx.write_adjlist(G, fh)
nx.draw(G)
plt.show()
I am trying to export it with below code and trying to change the color of some nodes. But it is generating different graph.
filename = "ipRandomGrid.txt"
fh=open(filename, 'rb')
G=nx.Graph()
G=nx.read_adjlist("ipRandomGrid.txt")
pos=nx.random_layout(G)
nx.draw_networkx_nodes(G,pos,nodelist=['1','2'],node_color='b')
nx.draw(G)
plt.show()
How to generate the same graph with few changes in color of some nodes?
If I understand the problem you're having correctly, the trouble is here:
pos=nx.random_layout(G)
nx.draw_networkx_nodes(G,pos,nodelist=['1','2'],node_color='b')
nx.draw(G)
You create a random layout of the graph in the first line, and use it to draw nodes '1' and '2' in the second line. You then draw the graph again in the third line without specifying the positions, which uses a spring model to position the nodes.
Your graph has no extra nodes, you've just drawn two of them in two different positions. If you want to consistently draw a graph the same way, you need to consistently use the pos you calculated. If you want it to be the same after storing and reloading, then save pos as well.
The easiest way to store node position data for your case might be using Python pickles. NetworkX has a write_gpickle() function that will do this for you. Note that the positions are already available as node attributes when you generate a random geometric graph so you probably want to use those when drawing. Here is an example of how to generate, save, load, and draw the same graph.
In [1]: import networkx as nx
In [2]: G=nx.random_geometric_graph(10,0.5)
In [3]: pos = nx.get_node_attributes(G,'pos')
In [4]: nx.draw(G,pos)
In [5]: nx.write_gpickle(G,'rgg.gpl')
In [6]: H=nx.read_gpickle('rgg.gpl')
In [7]: pos = nx.get_node_attributes(H,'pos')
In [8]: nx.draw(H,pos)