3
votes

I've a problem using Networkx to calculate Djisktra's Shortest Path in Python. I'm trying to draw only the shortest path returned by Djikstra's method because there are so many nodes and edges to draw.

I already have:

A = nx.dijkstra_path(g,'source','target')

It works good. After that I have:

noCor = ["blue" if n in A else "red" for n in g.nodes()]
pos = nx.spring_layout(g)
nx.draw_networkx_nodes(g, pos=pos, node_color=noCor)
nx.draw_networkx_edges(g, pos=pos)
fig = plt.axis('off')
fig = plt.gcf()
fig.set_size_inches(52.08,52.08)
fig.savefig("Djikstra.png",dpi=96)

But it will save all graph. Can someone help me, please?

Many thanks!

1

1 Answers

3
votes

TL/DR: just do this:

pos = nx.spring_layout(g)
h = g.subgraph(A)
nx.draw_networkx_nodes(h,pos=pos, node_color='b') #or even nx.draw(h,pos=pos,node_color='b') to get nodes and edges in one command
nx.draw_networkx_edges(h,pos=pos)

full answer:

You want to just plot the nodes in A and the edges in the path. You can actually avoid noCor altogether using the nodelist arguement which specifies which nodes to draw.

nx.draw_networkx_nodes(g,pos=pos, nodelist = A, node_color = 'b')

To plot just the edges corresponding to A, you need to figure out what those are. The easiest way I am aware of is

h = g.subgraph(A)

Then h is the subgraph induced on the nodes A. It has all edges in A. I am 99.9% sure (but haven't checked through a formal proof) that if A is the shortest path between two nodes (as returned by Dijkstra) then there aren't any other edges between the nodes in A except the ones in the path. So h.edges() will give the edges for A.

nx.draw_networkx_edges(g,pos=pos, edgelist = h.edges())

A more compact form would do it as:

pos = nx.spring_layout(g)
h = g.subgraph(A)
nx.draw_networkx_nodes(h,pos=pos, node_color='b') #or even nx.draw(h,pos=pos,node_color='b') to get nodes and edges in one command
nx.draw_networkx_edges(h,pos=pos)

You might ask why I defined pos with respect to g rather than h. It's because maybe you'd want to draw some other nodes in g into your figure later or some other figure, and it's useful then to have consistent positions. If you just do it with respect to h, it'll basically want to create a straight line.


Some comments on your command nx.draw_networkx_nodes(g, pos=pos, node_color=noCor). This tells it to draw all the nodes in g with the colors from noCor [and it will color the nodes based on the order the color appears in noCor and the order the nodes appear in g.nodes()]. Finally, note you need to use colors that matplotlib will recognize (see http://matplotlib.org/api/colors_api.html). In this case:

noCor = ["b" if n in A else "r" for n in g.nodes()]