4

我写了一个代码将我的转换MultiDiGraph()pydot图表以显示自循环和箭头,但转换后,pydot图表A失去了所有属性G。如何更改图形的节点大小A并将它们设置为等于node_sizes[]列表中的相应值,就像我所做的那样G

代码:

def draw_graph(graph, size):

    # extract nodes from graph
    nodes = set([n1 for n1, n2 in graph] + [n2 for n1, n2 in graph])
    print("Nodes ",nodes,"\n")

    node_sizes = []

    for n in nodes:
        #Scaling up the node importance by a factor of 2000 to make it visible
        node_sizes.append( size[n] * 2000)

    print("Node size ",node_sizes,"\n")

    # create networkx graph
    G=nx.MultiDiGraph()

    G.add_edges_from(edges)
    G.add_nodes_from(nodes)

    edge_colours = ['black' for edge in G.edges()]

    pos = nx.spring_layout(G)
    nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), node_size = node_sizes)
    nx.draw_networkx_labels(G, pos)
    nx.draw_networkx_edges(G, pos, edge_color='black', arrows=True)

    plt.show()

    # render pydot by calling dot, no file saved to disk
    A=nx.to_pydot(G, strict=True)

    png_str = A.create_png(prog='dot')

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

    # plot the image
    imgplot = plt.imshow(img, aspect='equal')
    plt.show(block=False)
4

1 回答 1

2

networkx使用节点和边标记的属性在转换期间设置节点和边的DOT属性。networkx.MultiDiGraph例如,g.add_node(1, label='first node')设置label属性:

import networkx as nx

graph = nx.MultiDiGraph()
graph.add_node(1, label='first node')
pd = nx.drawing.nx_pydot.to_pydot(graph)
print(pd.to_string())
# output:
# 'digraph  {\n1 [label="first node"];\n}\n'

(另外:调用函数nx.drawing.nx_pydot.to_pydot而不是nx.to_pydot,从 开始不存在networkx == 2.0。)

使用这个原理,设置height节点的属性(或者width,更多细节见下文),我们可以在绘制时改变节点的大小:

import networkx as nx

# create a `networkx` graph
graph = nx.MultiDiGraph()
graph.add_edge(1, 2)
graph.add_node(3, height=3)
graph.add_node(4, height=6)
# convert to a `pydot` graph
pd = nx.drawing.nx_pydot.to_pydot(graph)
pd.write_png('foo.png', prog='dot')

如果您想编写自己的转换器(而不是调用networkx.drawing.nx_pydot.to_pydot),请直接使用pydot图表:

import pydot

pd = pydot.Dot()
# create one node
nd = pydot.Node("a")
nd.set_height('"4"')
pd.add_node(nd)
# create another node
nd = pydot.Node("b")
nd.set_height('"2"')
pd.add_node(nd)
print(pd.to_string())
pd.write_png('bar.png')

与设置节点大小相关的属性是heightwidthfixedsize。来自 GraphViz 的文档

height

节点的高度,以英寸为单位。这被视为节点的初始最小高度。如果 fixedsize 为真,这将是节点的最终高度。否则,如果节点标签需要更大的高度来适应,则节点的高度将增加以包含标签。另请注意,如果输出格式为点,则赋予高度的值将是最终值。

如果节点形状规则,则宽度和高度相同。在这种情况下,如果显式设置了宽度或高度,则使用该值。在这种情况下,如果显式设置了宽度或高度,则使用两个值中的最大值。如果两者都没有明确设置,则使用两个默认值中的最小值。

以上结果使用networkx == 2.0pydot == 1.2.3

于 2017-11-06T19:18:29.223 回答