web-dev-qa-db-fra.com

Dessiner un graphique ou un réseau à partir d'une matrice de distance?

J'essaie de comploter/de croquis (Matplotlib ou autre python Library) d'un réseau 2D d'une matrice de grande distance où les distances seraient les bords du réseau esquissé et de la ligne et de la colonne Ses nœuds.

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] ]

Je cherche des croquis/tracer le réseau 2D de telle (plus gros: mille colonnes et lignes) Matrix de distance: le nœud 'A' est lié au nœud 'B' par une profondeur de bord de 0,3, nœuds 'c' et 'd 'serait attaché par une profondeur de bord de 0,1. Quels sont les outils/bibliothèques que je peux utiliser (la matrice de distance peut être convertie en matrice numpy) pour obtenir la projection de croquis/graphique de ce réseau? (Pandas, Matplotlib, Igraph, ...?) Et certains mènent à le faire rapidement (je ne définirais pas ma fonction d'auto-tkinter pour le faire ;-))? Merci pour vos réponses entrantes.

22
sol

Le programme graphvizneato essaie pour respecter les longueurs de bord. Doug montre un moyen à harnais neato utilisant NetworkX comme ceci:

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')

rendements

enter image description here


Si vous souhaitez générer un fichier DOT, vous pouvez le faire en utilisant

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

quels rendements

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"];
}

Le fichier png pourrait ensuite être généré à l'aide du programme graphvizneato Program:

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

Vous pouvez utiliser le package NetworkX, qui fonctionne parfaitement avec ce type de problèmes. Ajustez votre matrice pour supprimer une matrice numpie simple comme ceci:

DistMatrix =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] ])

puis importer NetworkX et l'utiliser

import networkx as nx
G = G=nx.from_numpy_matrix(DistMatrix)
nx.draw(G)

si vous souhaitez dessiner une version pondérée du graphique, vous devez spécifier la couleur de chaque bord (au moins, je n'ai pas pu trouver de manière plus automatisée de le faire):

nx.draw(G,Edge_color = [ i[2]['weight'] for i in G.edges(data=True) ], Edge_cmap=cm.winter )
16
EnricoGiampieri