Python 将网络图转换为graphviz

Python 将网络图转换为graphviz,python,networkx,graphviz,pydot,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 imp

我很难在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)
TLDR(a)使用neato,而不是点绘制(b)点文件中的位置属性应为“100200!”格式。不要重复引用它,并添加一个!马克

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

在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

现在再试一次:

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 
现在,这些立场得到尊重:

边缘标签和图像大小 dot手册和本网站都有关于如何绘制边标签的信息(例如或),显然,您需要在图形中添加一些属性(请参阅“使用关键字将数据关联到边”:

不清楚您所说的“plt.figure命令不起作用”是什么意思,但这与这里的networkx问题相去甚远,因此我认为最好发布一个新的问题,找出问题并对其进行全面解释

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=风格化的微小;neato-s-Tpng$F.dot>$F.png


您好,谢谢您的帮助,并为更多的noob道歉questions@qfd没问题。如果答案有助于解决你的问题,请考虑接受它()!回答得好,谢谢。我在尝试动态构建pos分配时收到了“expected two Double”投诉,直到我提前为它构建了字符串值。对于每个节点,从一个“VAL”位置数组中,我构建了一个pos字符串,然后分配给它:范围内r的行=[“a”,“B”,“C”,“D”,“E]:x=str(VAL[r][7]+0.0)y=str(VAL[r][8]+0.0)+”!“posstr=x+”,“+y网络。节点(行[r],pos=posstr)哇,谢谢!!对于我来说,无论是有格式还是没有格式!但是,如果我不放置它,则节点的位置与我指定的位置完全相同,而如果我放置它,则位置接近,但与我指定的位置不完全相同。我想知道这是否意味着它们被视为“初始”位置,然后放松到接近它们的位置。你知道为什么会这样吗?
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 
}