【问题标题】:Getting layout coordinates of graph vertices using python, networkx, pygraphviz使用 python、networkx、pygraphviz 获取图形顶点的布局坐标
【发布时间】:2017-12-23 19:18:34
【问题描述】:

我想使用 NetworkX 创建一个图形,使用 Graphviz 布局图形(通过 pygraphviz)。我已经成功运行了NetworkX pygraphviz examples documentation中的所有示例

我的问题是 - 如何将顶点的坐标(x,y)和尺寸(宽度,高度)返回到 NetworkX 图中。 这就是目标。我只想要 Graphviz 的布局功能,而不是绘图功能。使用这个堆栈(NetworkX、pygraphviz、graphviz)有可能吗?还有什么办法吗?

背景动机是这样的。 Graphviz 输出 png、ps、svg 等多种格式。 但我不想受到 Graphviz 处理的格式的限制。 我希望能够对布局结果进行后处理,甚至 如果我最终输出像 Graphviz 支持的流行格式。

更新:为了清楚起见,我已经重写了问题。关于 Graphviz 输出格式的建议没有抓住重点。这是我需要的布局数据

Update2:一个建议是以某种格式输出 Graphviz,然后我可以从中解析布局数据。该建议是针对 SVG 的。 我曾考虑过这种可能性。 Graphviz 输出 json(根据Graphviz output formats documentation page)。我无法让它在我的 Windows 安装上运行——由于某种原因,并非所有的输出格式都存在)。然而,正是这种方法让我感到不安。解析用于创建该输出的数据的格式化输出似乎是倒退的。我认为数据本身应该是可用的。

Update 3 - 有一个类似的问题 - How to get the coordinates from layout from graphviz?。答案之一建议使用 NetworkX。然而,答案使用 NetworkX 而不是 Graphviz 制作的布局。答案的作者不知道如何获取 Graphviz 布局数据。所以我的问题仍然相关,尚未得到回答

更新 4 - 现在是 07-2019,我仍然没有找到解决此问题的方法。我将一个答案标记为已接受 - 但需要注意的是 - 尽管在该答案中找到了很好的建议,但我仍然一无所知

【问题讨论】:

    标签: python networkx graphviz pygraphviz graph-layout


    【解决方案1】:

    Michael,我重新阅读了您的问题和 cmets,并使用了我知道有效的工具(而且我知道如何使用),这就是我在您的情况下会做的事情。我会在 DOT/GraphViz 中绘制您的图表,然后选择一种人类可读且易于解析的格式,例如 SVG、“plain”,甚至是 x-dot。为什么?不是要获取图形本身——其中一些甚至无法实现图形——而是因为这些格式是人类可读的并且包含不同绘图组件的 X-Y 坐标。您可以根据自己的目的使用这些坐标和大小。我刚刚做的一个简单图表的一些片段应该说明。 SVG优先

    <svg width="89pt" height="188pt"
    
    <g id="node1" class="node"><title>A</title>
    <ellipse fill="none" stroke="black" cx="54" cy="-162" rx="27" ry="18"/>
    <text text-anchor="middle" x="54" y="-158.3" font-family="Times New Roman,serif" font-size="14.00">A</text>
    

    或者以“普通”格式,也许是最简单的解析:

    graph 1 0.75 1.5
    node A 0.375 1.25 0.75 0.5 A solid ellipse black lightgrey
    node B 0.375 0.25 0.75 0.5 B solid ellipse black lightgrey
    edge A B 4 0.375 0.99579 0.375 0.88865 0.375 0.7599 0.375 0.64045 solid black
    stop
    

    或类似 html 的 VML:

    <v:oval style="position:absolute; left: 0.00; top: 0.00; width: 54.00; height: 36.00" filled="false"  >
    

    等等... 不难想象解析出各种元素的所有 X-Y 轴并根据您认为合适的方式重新调整它们的用途。

    【讨论】:

    • JLH,我很了解 SVG。 Graphviz 也输出 SVG。但是,我想获取布局数据(节点的 x、y、宽度、高度)而不是任何类型的输出格式。我会自己处理输出。这是我不想处理的布局逻辑。我认为我在问题中明确了我想要的功能。我错了。我会更正问题
    • JLH,重新阅读您的答案,我意识到我第一次没有理解它。你建议我让 Graphviz 创建一个 SVG 文件,然后解析 SVG 以获取布局数据?如果这是您的建议,那么我的反对意见是 - Graphviz 支持使用布局数据更容易解析格式,甚至是 json。这就是他们的文档所说的。由于某些莫名其妙的原因,我的 Graphviz 的 Windows 安装中无法使用 json 格式。但无论哪种方式,如果有办法通过 pygraphviz 从核心库本身获取数据,解析输出文件似乎是倒退的。
    • @Michael 是的,我选择了 SVG,因为它是 XML,但我在上面编辑的答案中提到了其他一些。在我的 GraphViz 版本中,我也没有选择输出到 JSON 的选项,但是有许多人类可读的输出格式。这只是您提出的问题的一种可行的解决方案。
    • 我编写了一个普通解析器,但由于某种原因,它没有给我所需的所有项目 - 它没有给我 IIRC 的 sements(节点组)。我会重新审视它——这是一种可行的方法。但是,我似乎在 pygraphviz 方面取得了一些进展,将继续这样做,直到卡住或让它工作。将在此处发布更新
    • 我已将此答案投票为已接受。但是 GraphVis 的问题在我的机器上仍然存在。我认为使用 GraphVis 是有风险的。不幸的是,我没有找到更好的库/工具
    【解决方案2】:

    关于更新 4

    现在仍然是 2019 年,但这非常适合我的需求

    import networkx as nx
    G = nx.complete_graph(10)
    pos = nx.drawing.nx_agraph.graphviz_layout(G, prog='dot')
    print(pos)
    

    给我

    {0: (327.0, 666.0), 1: (504.0, 594.0), 2: (327.0, 522.0), 3: (449.0, 450.0), 4: (283.0, 378.0), 5: (283.0, 306.0), 6: (473.0, 234.0), 7: (287.0, 162.0), 8: (418.0, 90.0), 9: (287.0, 18.0)}
    

    节点和位置的字典!

    问候 dom

    【讨论】:

      【解决方案3】:

      这是另一种解决方案。 它与 Dominik Ku​​mmer 的不同之处在于它公开了 pygraphviz.AGraph 对象,从而可以指定任意 gaphviz 属性来自定义布局。

      import networkx as nx
      import pygraphviz as pgv
      
      g = nx.complete_graph(10)
      ag = nx.drawing.nx_agraph.to_agraph(g)
      ag.layout(prog='dot')
      layout = [ag.get_node(n).attr['pos'] for n in ag.nodes()]
      layout = [[int(ss) for ss in s.split(",")] for s in layout]
      print(layout)
      
      

      给我:

      [[327, 666], [504, 594], [327, 522], [449, 450], [283, 378], [283, 306], [473, 234], [287, 162], [418, 90], [287, 18]]
      
      

      【讨论】:

        【解决方案4】:

        PyGraphviz 没有用于检索和设置布局信息(例如节点形状、边缘路由等)的 API。我不知道 Graphviz C 库的这些部分有任何 Python 接口。 Graphviz 本身确实提供了一个 Python 接口,包括渲染器,但我认为它也不完全符合您的要求 - 请参阅 http://www.graphviz.org/pdf/gv.3python.pdf

        最简单的方法可能确实是按照@JHL 的建议生成 SVG。

        【讨论】:

          猜你喜欢
          • 2017-09-13
          • 2021-02-28
          • 2014-03-25
          • 2014-05-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多