在 python 中使用 igraph 创建顶点之间具有特定距离的网络

Creating network with specific distances between vertices using igraph in python

我正在学习如何将某些集群的关系可视化为图形。假设我有 10 个簇 (0-9),我已经计算出它们之间的距离并将其存储在名为 cluster_dist 的字典中,它看起来像这样:

defaultdict(int,
        {('9', '2'): 90.0541376578846,
         ('1', '5'): 35.89579773471981,
         ('0', '2'): 35.89411581688678,
         ('5', '9'): 38.71629863467774,
         ('3', '5'): 4.263508474490007,
         ('2', '8'): 23.178581625571567,
         ('2', '7'): 75.21291397588608,
         ('1', '2'): 5.785812660966547,
         ('4', '6'): 5.785812660966547,
         ('1', '4'): 5.785812660966547})

所以这本字典的键是表示边的元组,这些键的值是我在每个集群之间计算的一​​种距离。距离越大,我希望它们在图表上越远。

是否可以使用这种输入创建图表?我正在尝试这样的事情:

g.add_vertices(10)

for clusters, dist in cluster_dist.items():

    a,b = map(int, list(clusters))
    g.add_edge(a, b, weight = dist )

但在这里我不确定如何以将权重解释为距​​离的方式绘制它。我对图形和 igraph 完全是个菜鸟,所以我敢打赌有更好的方法可以将距离属性分配给每条边。

是否可以用节点之间的任何一组预定距离来表示网络?如果是这样,使用 python 中的 igraph 执行此操作的最佳方法是什么?如果在数学上不可能生成代表给定距离集的网络,是否有任何方法来表示近似值?

感谢您的宝贵时间:)

在理解了布局的概念并深入研究了使用权重计算布局的可用函数之后,我找到了表示聚类距离的方法。

import igraph as ig

g = ig.Graph()
g.add_vertices(10)

for clusters, dist in cluster_dist.items():
    
    a,b = map(int, list(clusters))
    g.add_edge(a, b, weight = 1/dist )
    
l = g.layout_fruchterman_reingold(weights=splicing_net.es['weight'])

ig.plot(g, layout=l,  vertex_label=range(10), edge_width=ig.rescale([1/x for x in splicing_net.es["weight"]], out_range=(0.03, 3)))

到目前为止,Fruchterman-Reingold 正在生成美观的加权网络。如果有人知道遵循集群距离集计算布局的其他算法,请告诉我:)

使用 networkxkamada_kawai_layout 作为布局尊重距离。

import networkx as nx
import matplotlib.pyplot as plt
cluster_dist = \
        {('9', '2'): 90.0541376578846,
         ('1', '5'): 35.89579773471981,
         ('0', '2'): 35.89411581688678,
         ('5', '9'): 38.71629863467774,
         ('3', '5'): 4.263508474490007,
         ('2', '8'): 23.178581625571567,
         ('2', '7'): 75.21291397588608,
         ('1', '2'): 5.785812660966547,
         ('4', '6'): 5.785812660966547,
         ('1', '4'): 5.785812660966547}

# convert to graph
G = nx.Graph()
for (node1,node2), weight in cluster_dist.items():
    G.add_edge(node1, node2, weight=weight)
# compute layout for plotting
pos = nx.kamada_kawai_layout(G, weight='weight')
nx.draw(G,pos)
# next code for labels is not really necessary, but I think it makes it clearer
labels = {k: round(v,2) for k,v in nx.get_edge_attributes(G,'weight').items()}
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
nx.draw_networkx_labels(G,pos)

plt.show()

输出: