python-3.x 如何用networkx绘制平面图?

sd2nnvve  于 2023-02-26  发布在  Python
关注(0)|答案(2)|浏览(174)

我正在尝试用python包“matplotlib”和“networkx”绘制一个有向图的平面图。
我尝试过使用“networkx.planar_layout”来设置图中的节点位置,但不喜欢这样的结果。
在下面的示例中,“graph”是一个(平面)有向图。字典“graph”的键是节点。键的值是一个列表,其中包含此节点的所有邻居:

import networkx as nx
import matplotlib.pyplot as plt

graph = {'s1': ['v', 't1','w'],
     's2': ['t1','s1'],
     's3': ['v','w'],
     's4': ['x','y'],
     'x': ['v','w'],
     'v': ['t1', 'w'],
     'w': ['y','t1','t2'],
     'y': ['v','t1','t2'],
     't1': [],
     't2': []
     }

def main(G):
    fig = plt.figure()
    fig.show()

    graph = nx.DiGraph()

    for v in G.keys():
        graph.add_node(v)

    for delta in G.items():
        for w in delta[1]:
            graph.add_edge(delta[0],w)

    posit = nx.planar_layout(G)

    nx.draw(graph, posit , with_labels = True)
    fig.canvas.draw()

main(graph)

我得到的图像可以在https://imgur.com/fXP4GTq上看到
我不喜欢的是节点排列的方式会导致边的“堆叠”,例如,从图中无法判断边的位置(s2,t1)实际上结束,因为边缘在图像的这一部分中全部重叠(我甚至不认为这符合我的图的平面描绘的定义,这很奇怪,因为我使用的布局被称为“planar_layout”,而图实际上是平面的)。
有没有更好的方法来策划这件事?

ne5o7dgx

ne5o7dgx1#

我发现了一个函数可以帮助:我使用"nx. draw_planar"代替"nx. draw",如下所示:

def main(G):
    fig = plt.figure()
    fig.show()

    graph = nx.DiGraph()

    for v in G.keys():
        graph.add_node(v)

    for delta in G.items():
        for w in delta[1]:
            graph.add_edge(delta[0],w)

    #posit = nx.shell_layout(G) #ISN'T NEEDED ANYMORE

    nx.draw_planar(graph,with_labels = True, alpha=0.8) #NEW FUNCTION
    fig.canvas.draw()

    main(graph)

我得到以下结果:

这个解决方案的问题是我不能像以前的版本那样用"posit"保存节点位置,但是我想在后面的程序中使用它们,有人知道我如何不使用networkx的布局来获得它们吗?

iezvtpos

iezvtpos2#

import json
from random import random

import networkx as nx
import matplotlib.pyplot as plt

def draw(n : dict):
    g = nx.PlanarEmbedding()
    g.set_data(n)
    pos = nx.planar_layout(g)  # here are your positions.
    # pos = nx.spring_layout(g, pos=pos, seed=int(2**32 - 1 * random()))
    nx.draw_networkx(g, pos, with_labels=True)
    plt.show()

if __name__ == '__main__':
    j_obj = {}
    with open('planar.json', 'r') as infile:
        nodes = json.load(infile)
        infile.close()
    draw(nodes)

planar.json

{
   "s1": ["s2","t1","w", "v"],
   "s2": ["t1","s1"],
   "s3": ["w","v"],
   "s4": ["x","y"],
   "x": ["v","w","s4"],
   "v": ["s1","s3","w","x","y","t1"],
   "w": ["t1","t2","y","x","v","s3","s1"],
   "y": ["v","s4","w","t2","t1"],
   "t1": ["s2","v","y","w","s1"],
   "t2": ["y","w"]
}

相关问题