pythongraphplotsocial-networking

Drawing a graph or a network from a distance matrix?


I'm trying to plot/sketch (matplotlib or other python library) a 2D network of a big distance matrix where distances would be the edges of the sketched network and the line and column its nodes.

DistMatrix =
[       'a',   'b',     'c',    'd'],
['a',   0,      0.3,    0.4,    0.7],
['b',   0.3,    0,      0.9,    0.2],
['c',   0.4,    0.9,    0,      0.1],
['d',   0.7,    0.2,    0.1,    0] ]

I'm searching to sketch/plot the 2d network from such (bigger: thousand of columns and lines) distance matrix: node 'a' is linked to node 'b' by an edge depth of 0.3, nodes 'c' and 'd' would be tied by an edge depth of 0.1. What are the tools/libraries I can used (distance matrix can be converted into numpy matrix) to get the sketch/graphical projection of such network? (pandas, matplotlib, igraph,...?) and some leads to do that quickly (I would not define my self Tkinter function to do that ;-) ) ? thanks for your incoming answers.


Solution

  • The graphviz program neato tries to respect edge lengths. doug shows a way to harness neato using networkx like this:

    import networkx as nx
    import numpy as np
    import string
    
    dt = [('len', float)]
    A = np.array([(0, 0.3, 0.4, 0.7),
                   (0.3, 0, 0.9, 0.2),
                   (0.4, 0.9, 0, 0.1),
                   (0.7, 0.2, 0.1, 0)
                   ])*10
    A = A.view(dt)
    
    G = nx.from_numpy_matrix(A)
    G = nx.relabel_nodes(G, dict(zip(range(len(G.nodes())),string.ascii_uppercase)))    
    
    G = nx.drawing.nx_agraph.to_agraph(G)
    
    G.node_attr.update(color="red", style="filled")
    G.edge_attr.update(color="blue", width="2.0")
    
    G.draw('/tmp/out.png', format='png', prog='neato')
    

    yields

    enter image description here


    If you want to generate a dot file, you can do so using

    G.draw('/tmp/out.dot', format='dot', prog='neato')
    

    which yields

    strict graph {
        graph [bb="0,0,226.19,339.42"];
        node [color=red,
            label="\N",
            style=filled
        ];
        edge [color=blue,
            width=2.0
        ];
        B    [height=0.5,
            pos="27,157.41",
            width=0.75];
        D    [height=0.5,
            pos="69,303.6",
            width=0.75];
        B -- D   [len=2.0,
            pos="32.15,175.34 40.211,203.4 55.721,257.38 63.808,285.53"];
        A    [height=0.5,
            pos="199.19,18",
            width=0.75];
        B -- A   [len=3.0,
            pos="44.458,143.28 77.546,116.49 149.02,58.622 181.94,31.965"];
        C    [height=0.5,
            pos="140.12,321.42",
            width=0.75];
        B -- C   [len=9.0,
            pos="38.469,174.04 60.15,205.48 106.92,273.28 128.62,304.75"];
        D -- A   [len=7.0,
            pos="76.948,286.17 100.19,235.18 167.86,86.729 191.18,35.571"];
        D -- C   [len=1.0,
            pos="94.274,309.94 100.82,311.58 107.88,313.34 114.45,314.99"];
        A -- C   [len=4.0,
            pos="195.67,36.072 185.17,90.039 154.1,249.6 143.62,303.45"];
    }
    

    The png file could then be generated using the graphviz neato program:

    neato -Tpng -o /tmp/out.png /tmp/out.dot