【问题标题】:converting network graph to graphviz将网络图转换为 graphviz
【发布时间】:2018-03-01 00:02:35
【问题描述】:

我无法在 networkx 中可视化具有平行边的多向图,因此我使用了 pydot,但我遇到了两个问题

1) 我似乎无法理解为什么节点位置没有被固定我想在 x 和 y 指定的坐标处绘制它们 2)如何设置正在绘制的图形的大小 plt.figure 命令实际上不起作用 3)我如何添加边缘标签(如果我有的话)

非常感谢

import networkx as nx  
from io import StringIO
from io import BytesIO

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import networkx as nx


graph= nx.MultiGraph()                                                                                    

#add 4 nodes in the vertexs of a square. X and Y are the coordinates                                      
graph.add_node(1,x=100,y=100)                                                                             
graph.add_node(2,x=100,y=200)                                                                             
graph.add_node(3,x=200,y=100)                                                                             
graph.add_node(4,x=200,y=200)                                                                             
graph.add_edge(1,2)                                                                                       
graph.add_edge(2,1)   
graph.add_edge(3,1)
graph.add_edge(3,4)                                                                                       
graph.add_edge(4,1)                                                                                       
                                                                                                         # assign positions                                                                                        
for n in graph:                                                                                           
    graph.node[n]['pos'] = '"%d,%d"'%(graph.node[n]['x'], graph.node[n]['y'])                             
p = nx.drawing.nx_pydot.to_pydot(graph)                                                                                    

# render pydot by calling dot, no file saved to disk
png_str = p.create_png(prog='C:\\Anaconda3\\Library\\bin\\graphviz\\dot.exe')

# treat the dot output string as an image file
sio = BytesIO()
sio.write(png_str)
sio.seek(0)
img = mpimg.imread(sio)





plt.figure(figsize = (10,10))
imgplot = plt.imshow(img)

【问题讨论】:

    标签: python networkx graphviz pydot


    【解决方案1】:

    TLDR (a) 使用neato,而不是点来绘制 (b) pos attrs 的形式应该是“100,200!”在点文件中。不要双引号,并添加一个!标记。

    首先,并非所有的 graphviz 工具都支持位置。见docs

    在neato和fdp中,可以使用pos来设置节点的初始位置

    其次,一旦您使用读取pos 属性的工具,您会在输出中看到一些错误。要了解外部工具的问题,单独测试它更有意义,所以让我们这样做:

    nx.drawing.write_dot(graph, "test.dot")
    

    然后运行neato:

    > neato -Tpng test.dot >test1.png 
    Error: node 1, position "100,100", expected two doubles
    Error: node 2, position "100,200", expected two doubles
    Error: node 3, position "200,100", expected two doubles
    Error: node 4, position "200,200", expected two doubles
    

    您现在会看到格式不正确。因此,neato 继续对图表进行布局,就好像没有指定 pos 一样。

    for n in graph:
        graph.node[n]['pos'] = "{},{}!".format(
            graph.node[n]['x'], graph.node[n]['y'])
    

    现在再试一次:

    nx.drawing.write_dot(graph, "test_fix.dot")
    
    # note: the -n flag causes neato to use points rather than inches. 
    # see docs, and/or experiment with -s setting as well
    > neato -n -Tpng test_fix.dot >test2.png 
    

    现在尊重位置:

    边缘标签和图像尺寸

    点手册和这个网站都有关于如何绘制边缘标签的信息(例如How to add edge labels in Graphviz?Graphviz: Place edge label on the other side (II)),显然您需要在图表中添加一些属性(请参阅“使用关键字将数据关联到边缘” :https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.DiGraph.add_edge.html)

    不清楚您所说的“plt.figure 命令不起作用”是什么意思,但这与此处的 networkx 问题相去甚远,所以我认为最好发布一个新问题来隔离问题并解释它完全。

    【讨论】:

    • 您好,感谢您对更多菜鸟问题表示歉意
    • @qfd 没有问题。如果答案有助于解决您的问题,请考虑接受它 (click the green tick at the top left of the answer)!
    • 很好的答案,谢谢。我收到了“预期的两个双打”的抱怨,试图动态地构建 pos 分配,直到我提前为它构建了字符串值。对于每个节点,从“vals”位置数组中,我构建了一个 pos 字符串,然后分配它: rows=["A","B","C","D","E"] for r in range (len(rows)): x=str(vals[r][7]+0.0) y=str(vals[r][8]+0.0)+"!" posstr=x+","+y network.node(rows[r],pos=posstr)
    • 哇,谢谢!!对我来说,有和没有的格式!正在工作,但是,如果我放它,那么节点的位置正好等于我指定的位置,而如果我放它,那么位置很接近,但不完全是我指定的位置。我想知道这是否意味着它们被视为“初始”位置,然后放松到接近它们的位置。你知道为什么会这样吗?
    【解决方案2】:
    digraph G {
        graph [bb="0,0,270,396",
            sep="+6",
            splines=true
        ];
        node [label="\N",
            nodesep=.4,
            pin=true,
            style=invis
        ];
        edge [style=invis];
        {
            graph [rank=same];
            node [style=solid];
            1   [height=0.5,
                pos="27,378",
                width=0.75];
        }
        {
            graph [rank=same];
            node [style=solid];
            2   [height=0.5,
                pos="27,306",
                width=0.75];
            3   [height=0.5,
                pos="99,306",
                width=0.75];
            5   [height=0.5,
                pos="243,306",
                width=0.75];
        }
        {
            graph [rank=same];
            node [style=solid];
            c1  [height=0.5,
                pos="27,234",
                style=invis,
                width=0.75];
            6   [height=0.5,
                pos="99,234",
                width=0.75];
        }
    
        1 -> 2  [pos="e,27,324.1 27,359.7 27,351.98 27,342.71 27,334.11"];
        2 -> c1 [pos="e,27,252.1 27,287.7 27,279.98 27,270.71 27,262.11"];
    
    edge[constraint=false style=solid]  
    
    1 -> 2 [label=aaa ]
    1 -> 3 [label=abb] 
    1 -> 5 [label=abc ]
    1 -> 6   [label=aba]
    3 -> 6 
    }
    

    运行neato的Linux命令-注意“-s”选项
    F=stylized1Tiny;整洁 -s -Tpng $F.dot >$F.png;

    【讨论】:

      猜你喜欢
      • 2017-04-01
      • 2018-07-19
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-15
      • 1970-01-01
      • 2015-12-12
      相关资源
      最近更新 更多