visualization - NetworkX-style spring model layout for directed graphs in Graphviz / PyGraphviz -



visualization - NetworkX-style spring model layout for directed graphs in Graphviz / PyGraphviz -

networkx graph analysis, pygraphviz drawing, , they're designed work together. however, there's @ to the lowest degree 1 respect in networkx's graph drawing (via matplotlib) superior pygraphviz's graph drawing (via graphviz), namely networkx has spring layout algorithm (accessible via spring_layout function) directed graphs while pygraphviz has several spring layout algorithms (accessible via neato program, , others) lay out directed graphs if undirected graphs. graphviz / pygraphviz layout programme handles direction in graph dot, dot creates hierarchical layouts, not force-directed layouts.

here illustration shows difference between networkx , pygraphviz spring layouts of directed graphs:

import networkx nx import pygraphviz pgv import matplotlib.pyplot ppt edgelist = [(1,2),(1,9),(3,2),(3,9),(4,5),(4,6),(4,9),(5,9),(7,8),(7,9)] nxd = nx.digraph() nxu = nx.graph() gvd = pgv.agraph(directed=true) gvu = pgv.agraph() nxd.add_edges_from(edgelist) nxu.add_edges_from(edgelist) gvd.add_edges_from(edgelist) gvu.add_edges_from(edgelist) pos1 = nx.spring_layout(nxd) nx.draw_networkx(nxd,pos1) ppt.savefig('1_networkx_directed.png') ppt.clf() pos2 = nx.spring_layout(nxu) nx.draw_networkx(nxu,pos2) ppt.savefig('2_networkx_undirected.png') ppt.clf() gvd.layout(prog='neato') gvd.draw('3_pygraphviz_directed.png') gvu.layout(prog='neato') gvu.draw('4_pygraphviz_undirected.png')

1_networkx_directed.png:(http://farm9.staticflickr.com/8516/8521343506_0c5d62e013.jpg)

2_networkx_undirected.png:(http://farm9.staticflickr.com/8246/8521343490_06ba1ec8e7.jpg)

3_pygraphviz_directed.png:(http://farm9.staticflickr.com/8365/8520231171_ef7784d983.jpg)

4_pygraphviz_undirected.png:(http://farm9.staticflickr.com/8093/8520231231_80c7eab443.jpg)

the 3rd , 4th figures drawn identical arrowheads (the whole figure has been rotated, apart that, there's no difference). however, first , sec figures differently laid out - , not because networkx's layout algorithm introduces element of randomness.

repeatedly running code above shows not chance occurrence. networkx's spring_layout function apparently written on assumption if there arc 1 node another, sec node should closer centre of graph first (i.e. if graph described in edgelist directed, node 2 should closer node 9 nodes 1 , 3 are, node 6 should closer node 9 node 4 is, , node 8 should closer node 9 node 7 is; doesn't work see nodes 4 , 5 in first figure above, that's little issue compared getting both 2 , 9 near centre , 'error' point of view slight). in other words, networkx's spring_layout both hierarchical , force-directed.

that nice feature, because makes core/periphery structures more obvious in directed graphs (where, depending on assumptions you're working with, nodes without incoming arcs can considered part of periphery if have big numbers of outgoing arcs). @skyebend has explained below why layout algorithms treat directed graphs if undirected, graphs above show (a) networkx treats them differently, , (b) in principled way helpful analysis.

can replicated using pygraphviz / graphviz?

unfortunately documentation , commented source code networkx's spring_layout (actually fruchterman_reingold_layout) function provide no clue why networkx produces result does.

this result of using pygraphviz draw network using networkx spring_layout function (see own reply question below). 5_pygraphviz_plus_networkx.png: (http://farm9.staticflickr.com/8378/8520231183_e7dfe21ab4.jpg)

okay, think figured out i'm going reply own question. don't think can done in pygraphviz per se. however, 1 can instruct pygraphviz take node positions networkx peg them (using !) neato programme prevented doing except rubber-stamping node positions calculated spring_layout. add together next lines of code above:

for k,v in pos1.iteritems(): gvd.get_node(k).attr['pos']='{},{}!'.format(v[0]*10,v[1]*10) gvd.layout(prog='neato') gvd.draw('5_pygraphviz_plus_networkx.png')

the result not perfect -- had multiply co-ordinates 10 in order stop nodes beingness drawn on top of each other, (obviously) kludge -- it's improvement, i.e. nodes 0 indegree on outside (benefit of laying out networkx) , there proper arrowheads don't swallowed nodes (benefit of drawing pygraphviz).

i aware isn't strictly asked for, though (i.e. solution using pygraphviz / graphviz itself).

if can provide improve solution i'll happy!

edit: nobody's provided improve solution problem articulated above, i'm going take own reply signal works. however, i'm voting skyebend's reply because - although doesn't solve problem - it's useful contribution understanding underlying issues.

graph visualization graphviz networkx pygraphviz

Comments

Popular posts from this blog

web services - java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer -

Accessing MATLAB's unicode strings from C -

javascript - mongodb won't find my schema method in nested container -