使用Python按EID设置igraph边宽

1 投票
2 回答
1801 浏览
提问于 2025-04-18 07:06

这个问题听起来有点傻,但我就是在 igraph 的文档里找不到解决办法。我想这应该很简单,但我的 Python 技术不够好,搞不定。

我在使用 igraph 时,想找到我想操作的边,所以用到了 select 方法。这个方法返回的是边对象的引用。当我尝试更改边的宽度属性时,图表上并没有更新。

我的代码示例是寻找 A 和 B 这两个节点之间的边。

 source = g.vs.find(name = 'A')
 sink   = g.vs.find(name = 'B')
 edge   = g.es.select(_source = source, _target= sink)
 edge["edge_width"] = 20

但是当我绘制图形时,所有的边都是一样的。我哪里出错了呢?

补充一下:为了让事情更简单,这里有一个完整的代码示例,能生成这个问题。它只是创建了一个有 5 个节点(A 到 E)并且彼此完全连接的图形,并将其绘制到屏幕上。

import string
import igraph as ig

num_nodes = 5

alpha_list = list(string.ascii_uppercase)
alpha_list = alpha_list[:num_nodes]

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

for x in range (0, num_nodes + 1):
    for y in range (x, num_nodes):
        print "x: "+str(x)+", y: "+str(y)
        if (x != y):
            g.add_edge(x, y)

g.vs["label"] = g.vs["name"]

source = g.vs.find(name = 'A')
sink   = g.vs.find(name = 'B')

edge = g.es.select(_source = source, _target= sink)

edge["edge_width"] = 20

print edge.attributes()

layout = g.layout("circle")
ig.plot(g, layout = layout)

2 个回答

0

其实有两种方法可以设置单个边的“宽度”属性:

如果我理解你的问题,你是想在创建图形之后更新这个属性。

你可以这样做:

# get index of edge between vertices "A" and "B"
edge_index = g.get_eis("A", "B")
# set width attribute to 20
g.es[edge_index] = 20

另外,为什么不在构建图形的时候就指定这个属性呢?

你只需要在“add_edge”函数中添加宽度这个关键字参数。这里是你修改后的构建循环:

for x in range (0, num_nodes + 1):
    for y in range (x, num_nodes):
        print "x: "+str(x)+", y: "+str(y)
        if (x != y):
            # setting width 20 for "A" and "B"
            w = 20 if (x==0 and y==1) else 1
            g.add_edge(x, y, width=w)

希望这对你有帮助;)

2

我还是找不到一个简单的方法来查找和更改单个边的视觉属性,不过我通过这段代码搞定了(经过很多次尝试和错误)。

# Start a list of all edge widths, defaulted to width of 3
widths = [3] * len(g.es)

# Find edge ID
start_vertex = g.vs.find(name = start_name).index
end_vertex   = g.vs.find(name = end_name).index
edge_index   = g.get_eid(start_vertex, end_vertex)

# Change the width for the edge required
widths[edge_index] = 20

# Update the graph with the list of widths
g.es['width'] = widths

虽然当你想更新很多边的时候,这个方法很好用,但如果我只想更新一两个边,就显得特别麻烦。不过,既然能用,那就没关系了。

撰写回答