将网络图转换为graphviz

时间:2018-03-01 00:02:35

标签: python networkx graphviz pydot

我无法在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)

2 个答案:

答案 0 :(得分:0)

TLDR (a)使用neato,而非使用dot绘制(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一样。

automatic layout, ignoring pos attr

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 

现在尊重职位:

format of pos argument correct

边缘标签和图像尺寸

点手册和此网站都有关于如何绘制边缘标签的信息(例如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命令不能正常工作"但是这里离网络问题还很远,所以我认为最好发布一个新的问题来隔离问题并完全解释。

答案 1 :(得分:0)

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 =样式化的1Tiny; neato -s -Tpng $ F.dot> $ F.png;

enter image description here