networkx/igraph (Python) 上指定的边长度

发布于 2024-08-13 08:11:45 字数 238 浏览 3 评论 0原文

我想用我拥有的数据可视化一个网络,并想用特定的边长度来绘制它们。我使用Python,并且尝试过networkx和igraph来绘图,但似乎都分配了固定的边长度。

a.)我想知道我是否写错了代码或者这些软件包实际上没有能力。如何正确实现 networkx 或 igraph 的指定边长?

b.) 如果networkx 和igraph 不能做到这一点,您可以建议什么包? (最好是能承载8万个以上节点的。)

谢谢!

I wanted to visualize a network with the data I have and would like to graph them with specific edge lengths. I use Python, and I've tried networkx and igraph to plot but all seem to assign fixed edge lengths.

a.) I wonder if I did the codes wrong or the packages aren't really capable. How do you properly implement specified edge lengths for networkx or igraph?

b.) If networkx and igraph can't do it, what package could you possibly suggest? (Preferably one that can carry over 80 thousand nodes.)

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

追我者格杀勿论 2024-08-20 08:11:45

这应该可行:

import networkx as NX
import pygraphviz as PG

G = PG.AGraph()
nlist = "A B C D E".split()
a, b = "A A B", "B C D"
elist = zip(a.split(), b.split())

G.add_nodes_from(nlist)
G.add_edges_from(elist)
G.node_attr.update(color="red", style="filled")
G.edge_attr.update(color="blue", len="2.0", width="2.0")

print(G.edge_attr)
# returns {'color': 'red', 'width': '', 'len': '2.0'}

# add new edge with custom length (all others have length=2.0):
G.add_edge("C", "E", len="3.0", color="blue", width="2.0")

edge = G.get_edge("C", "E")
print(edge_attr)
# returns {'color': 'blue', 'width': '2.0', 'len': '3.0'}

# and you can confirm that introspection by drawing & printing this graph:
G.draw('somefolderandfilename.png', format='png', prog='neato')

大多数图形绘制算法都使用某些版本的 SMACOF,这当然会改变边长;然而,graphviz 布局引擎“neato”(作为上面“draw”的第二个参数提供)应该尽可能保留用户设置的边长。

我在这里使用的库确实足够坚固,可以处理 80,000 个节点。

This should work:

import networkx as NX
import pygraphviz as PG

G = PG.AGraph()
nlist = "A B C D E".split()
a, b = "A A B", "B C D"
elist = zip(a.split(), b.split())

G.add_nodes_from(nlist)
G.add_edges_from(elist)
G.node_attr.update(color="red", style="filled")
G.edge_attr.update(color="blue", len="2.0", width="2.0")

print(G.edge_attr)
# returns {'color': 'red', 'width': '', 'len': '2.0'}

# add new edge with custom length (all others have length=2.0):
G.add_edge("C", "E", len="3.0", color="blue", width="2.0")

edge = G.get_edge("C", "E")
print(edge_attr)
# returns {'color': 'blue', 'width': '2.0', 'len': '3.0'}

# and you can confirm that introspection by drawing & printing this graph:
G.draw('somefolderandfilename.png', format='png', prog='neato')

Most graph drawing algorithms use some version of SMACOF, which of course varies the edge length; however, the graphviz layout engine 'neato' (supplied as the 2nd argument to 'draw' above) ought to preserve, if at all possible, user-set edge lengths.

The library i used here is certainly sturdy enough to handle 80,000 nodes.

AFAIK、networkx 和 igraph 没有根据给定的一组边长度推断节点位置的布局函数。
然而, netgraph 是一个用于实现更好的网络可视化的 Python 库,它确实实现了所需的功能几何节点布局。在下面的示例中,我使用边列表来表示网络,但 netgraph 也接受 networkx、igraph 和 graph-tool Graph 对象。

#!/usr/bin/env python

import matplotlib.pyplot as plt

from netgraph import Graph # pip install netgraph OR conda install -c conda-forge netgraph

# right triangle
edge_length = {
    (0, 1) : 0.3,
    (1, 2) : 0.4,
    (2, 0) : 0.5,
}
edges = list(edge_length.keys())

fig, ax = plt.subplots()
Graph(edges, edge_labels=edge_length, node_layout='geometric',
      node_layout_kwargs=dict(edge_length=edge_length), ax=ax)
ax.set_aspect('equal')
plt.show()

但不想使用 netgraph 进行绘图,则可以使用 get_geometric_layout 函数计算节点位置:

from netgraph import get_geometric_layout

pos = get_geometric_layout(edges, edge_length)

但是< /strong>,netgraph 使用非线性优化从边长推断节点位置。该计算与节点数量的平方成正比。对于可以合理表示为链路图(即最多几百个节点)的网络,计算时间相当短(<2 秒),但我从未尝试过在 80k 节点上运行该过程,我怀疑需要几天时间才能完成。

AFAIK, networkx and igraph do not have a layout functions that infers node positions based on a given set of edge lengths.
However, netgraph, which is a python library for making better network visualisations, does implement the desired functionality in the geometric node layout. In the example below, I am using an edge list to represent the network, but netgraph also accepts networkx, igraph, and graph-tool Graph objects.

enter image description here

#!/usr/bin/env python

import matplotlib.pyplot as plt

from netgraph import Graph # pip install netgraph OR conda install -c conda-forge netgraph

# right triangle
edge_length = {
    (0, 1) : 0.3,
    (1, 2) : 0.4,
    (2, 0) : 0.5,
}
edges = list(edge_length.keys())

fig, ax = plt.subplots()
Graph(edges, edge_labels=edge_length, node_layout='geometric',
      node_layout_kwargs=dict(edge_length=edge_length), ax=ax)
ax.set_aspect('equal')
plt.show()

If you only want the node positions but you don't want to use netgraph for plotting, you can compute the node positions using the get_geometric_layout function:

from netgraph import get_geometric_layout

pos = get_geometric_layout(edges, edge_length)

However, netgraph uses a non-linear optimisation to infer the node positions from the edge lengths. This computation scales with the square of the number of nodes. For networks that can reasonably represented as link diagrams (i.e. up to a few hundred nodes) the computation time is reasonably short (<2 seconds) but I have never tried running the procedure on 80k nodes and I suspect it would take days to finish.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文