【问题标题】:Drawing a graph or a network from a distance matrix?从距离矩阵中绘制图形或网络?
【发布时间】:2012-11-10 21:30:28
【问题描述】:

我正在尝试绘制/绘制(matplotlib 或其他 python 库)大距离矩阵的二维网络,其中距离将是绘制网络的边缘以及其节点的线和列。

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

我正在搜索从这样的(更大:数千列和线)距离矩阵中绘制/绘制 2d 网络:节点“a”通过 0.3 的边缘深度链接到节点“b”,节点“c”和 'd' 将由 0.1 的边缘深度绑定。 我可以使用哪些工具/库(距离矩阵可以转换为 numpy 矩阵)来获取此类网络的草图/图形投影? (熊猫,matplotlib,igraph,...?)和一些导致快速做到这一点(我不会定义我自己的 Tkinter 函数来做到这一点;-))? 感谢您的回复。

【问题讨论】:

  • 理论上,这对于某些距离矩阵来说是不可能的。想象一下,例如所有条目为 1 的 4 x 4 距离矩阵。这定义了一个三维单纯形。无法将此图以等距方式嵌入到二维中。在这种情况下程序应该做什么?
  • 对,所以没有“边长”而是“连接两个节点的边深度”

标签: python graph plot social-networking


【解决方案1】:

graphviz 程序 neato 尝试遵守边长。 doug shows a way 像这样使用 networkx 来利用 neato

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

产量


如果要生成点文件,可以使用

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

产生

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

然后可以使用graphviz neato 程序生成png 文件:

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

【讨论】:

  • 我已经尝试了您建议的代码,适应了我的需要(删除 A.view),即使只有 7 个节点也无法正常工作。 G 是正确的。可能出了什么问题?我正在使用graphviz 2.36。
  • 这会导致我出现错误'module' object has no attribute 'to_agraph'。为了解决这个问题,我使用了stackoverflow.com/questions/35279733/…,而是使用了nx.drawing.nx_agraph.to_agraph
  • 如何在没有python的纯graphviz中绘制相同的图?
  • @Snochacz:我更新了答案以包含由networkx生成的点文件。
  • 我无法安装 pygraphviz。是否可以使用neato并使用graphviz包编写相同的算法(使用pydot)?
【解决方案2】:

您可以使用 networkx 软件包,它可以完美地解决此类问题。 调整您的矩阵以删除一个简单的 numpy 数组,如下所示:

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

然后导入networkx并使用它

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

如果你想绘制一个加权版本的图形,你必须指定每条边的颜色(至少,我找不到更自动化的方法来做到这一点):

nx.draw(G,edge_color = [ i[2]['weight'] for i in G.edges(data=True) ], edge_cmap=cm.winter )

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多