8

私はいくつかのプロジェクトでpygraphを使用しています。私はこの例を完了しました、それはうまくいきます。

ここで、問題は次のとおりです。グラフは画像形式(gif)で描画されます。必要なのは、gif画像に示されているグラフレイアウトの各ノードの実際の座標を取得することです。どうすればよいですか?私は試してみましたが、この問題の解決策を見つけることができませんでした。問題の解決策は、次の2つの行のいずれかを操作することであると思いました。

gv.layout(gvv,'dot')
gv.render(gvv,'png','europe.png')

前もって感謝します!

4

7 に答える 7

7

次のコマンドを使用して、レイアウト情報をグラフに追加できます。

gv.render(gvv)

次に、その属性を取得しているノードの位置を見つけますpos

n_france = gv.findnode(gvv, "France")
pos = gv.getv(n_france, "pos")

次に、実行する内容によっては、ドット座標をpng画像座標に変換する必要がある場合があります。ここから有用な情報を得ることができます:

http://www.graphviz.org/faq/#FaqCoordTransformation

グラフ単位から画像ピクセルまでの計算について詳しく説明しています。

これがあなたが探しているものであることを願っています。

于 2012-12-20T08:55:35.200 に答える
2

自分のニーズに完全に対応する同様のソリューションを見つけました

pos = nx.drawing.nx_agraph.graphviz_layout(G, prog='dot', args='-Grankdir=LR')

乾杯!

于 2019-09-11T17:15:57.180 に答える
2

pydotplusを使用すると、dot / gvファイルを読み込んで解析し、pydotplusが生成するデータ構造を調べることができますが、この内部表現は、ファイルに既に存在しない限り、posなどのすべてのノード属性を最初は持っていないようです。
ただし、.write_dot()を呼び出して、より詳細なドットファイルバージョンを生成することもできます。これを解析すると、結果のデータ構造にはすべてのノードのpos(およびスプラインのpos)があるように見えます

注:冗長ファイルでノードの後に​​角かっこが付いているテキストはノードとして解析されるため、ノードリストに偽の余分な要素が含まれている可能性があるため、インデックスではなく名前でノードにインデックスを付けるのが最適な場合があります。

次の(少し編集された)Spyderプロンプトでの実験では、.graph_from_dot_file()、次に.write_dot()という簡潔なドットファイルinterior.gv(ノードのposがない)があります。次に、冗長に生成されたファイルで.graph_from_dot_file()を再度実行し、必要に応じてposを見つけます。

import pydotplus as pdp

interior = pdp.graphviz.graph_from_dot_file('interior.gv')

interior.write_dot('interior2.dot')
Out[210]: True

interior2 = pdp.graphviz.graph_from_dot_file('interior2.dot')

interior2.get_nodes()[3].get_pos()
Out[214]: '"213.74,130"'
于 2020-09-22T22:40:34.510 に答える
1

Networkxはこれを行うことができます:

import networkx as nx

def setup_europe():
    G = nx.Graph()

    G.add_edge("Portugal", "Spain")
    G.add_edge("Spain","France")
    G.add_edge("France","Belgium")
    G.add_edge("France","Germany")
    G.add_edge("France","Italy")
    G.add_edge("Belgium","Netherlands")
    G.add_edge("Germany","Belgium")
    G.add_edge("Germany","Netherlands")
    G.add_edge("England","Wales")
    G.add_edge("England","Scotland")
    G.add_edge("Scotland","Wales")
    G.add_edge("Switzerland","Austria")
    G.add_edge("Switzerland","Germany")
    G.add_edge("Switzerland","France")
    G.add_edge("Switzerland","Italy")
    G.add_edge("Austria","Germany")
    G.add_edge("Austria","Italy")
    G.add_edge("Austria","Czech Republic")
    G.add_edge("Austria","Slovakia")
    G.add_edge("Austria","Hungary")
    G.add_edge("Denmark","Germany")
    G.add_edge("Poland","Czech Republic")
    G.add_edge("Poland","Slovakia")
    G.add_edge("Poland","Germany")
    G.add_edge("Czech Republic","Slovakia")
    G.add_edge("Czech Republic","Germany")
    G.add_edge("Slovakia","Hungary")
    return G

G = setup_europe()

ドットファイルを書く:

nx.write_dot(G, '/tmp/out.dot')

ノードの位置を計算します。

pos = nx.pygraphviz_layout(G, prog = 'dot')
print(pos)
# {'Netherlands': (713.86, 167.0), 'Italy': (473.86, 389.0), 'Czech Republic': (100.86, 241.0), 'Portugal': (879.86, 315.0), 'England': (1024.9, 241.0), 'Denmark': (568.86, 167.0), 'Poland': (100.86, 167.0), 'Scotland': (1024.9, 389.0), 'France': (571.86, 315.0), 'Belgium': (713.86, 19.0), 'Austria': (320.86, 167.0), 'Slovakia': (156.86, 315.0), 'Wales': (990.86, 315.0), 'Switzerland': (473.86, 241.0), 'Hungary': (294.86, 241.0), 'Germany': (465.86, 93.0), 'Spain': (879.86, 241.0)}

pngをレンダリングする:

agraph = nx.to_agraph(G)
agraph.draw("/tmp/europe.png", format = 'png', prog = 'dot')

ここに画像の説明を入力してください

于 2012-12-18T20:43:26.967 に答える
1

pydot / dotだけを使用して、SVGを生成し、SVGからノードの位置を読み取ることでそれを行うことができます。少しハッキーですが、十分に確実に機能します

from xml.dom import minidom
import pydot
from io import BytesIO
def extract_node_positions(
    in_dot: pydot.Dot
) -> Dict[str, Tuple[str, float, float]]:
    """
    Extract the x,y positions from a pydot graph by rendering
    Args:
        in_dot: the graph to render

    Returns:
        a list of all the nodes

    Examples:
        >>> g = pydot.Dot()
        >>> g.add_node(pydot.Node("A"))
        >>> g.add_node(pydot.Node("B"))
        >>> g.add_node(pydot.Node("C"))
        >>> g.add_edge(pydot.Edge("A", "B"))
        >>> g.add_edge(pydot.Edge("B", "C"))
        >>> extract_node_positions(g)
        {'A': ('A', 27.0, -157.8), 'B': ('B', 27.0, -85.8), 'C': ('C', 27.0, -13.8)}
    """
    node_mapping = {f'node{i}': k.get_name() 
                    for i, k in enumerate(in_dot.get_nodes(), 1)}
    svg_io = BytesIO(in_dot.create_svg())
    doc = minidom.parse(svg_io)  # parseString also exists
    node_dict = {node_mapping[p.getAttribute('id')]: (c_text.firstChild.data,
                                        float(c_text.getAttribute('x')),
                                        float(c_text.getAttribute('y')))

                 for p in doc.getElementsByTagName("g") if "node" == p.getAttribute('class').lower()
                 for c_text in p.getElementsByTagName('text')
                 }
    doc.unlink()
    return node_dict
于 2020-02-11T09:17:26.287 に答える
1

ファイルに書き込む代わりに、Python内からバイナリデータ文字列としてGraphvizレンダリングコマンド(ドットなど)の結果に直接アクセスするには、GraphまたはDigraphオブジェクトのpipe()メソッドを使用します。

h = Graph('hello'、format ='svg')

h.edge('Hello'、'World')

print(h.pipe()。decode('utf-8'))

于 2020-04-14T18:53:30.330 に答える
0

私は最近これに苦労しました、そしてここでの答えはいくつかの助けでしたが、そこには完全ではありませんでした。networkxに関する提案は正しい方向に進んでいます。Networkxはpygraphvizを使用してgraphvizとインターフェイスするため、必要に応じて代わりにpygraphvizを直接使用できます。

import pygraphviz as pgv
G = pgv.AGraph(strict=False,directed=True)
# add nodes and edges
G.add_edge(1,2)
G.add_edge(2,1)
# generate a layout--this creates `pos` attributes for both nodes and edges
G.layout(prog="dot") 
#change something about the graph that would change the layout, e.g.,
edge = G.get_edge("1", "2")
edge.attr["label"] = "test label"
# create the graph using the layout already generated; note, do not provide `prog`
G.draw("test.pdf")
# compare it to a newly generated layout
G.draw("test2.pdf", prog="dot")

重要な部分は、コマンドによってすでに生成されているノードとエッジの位置を使用する場合は、コマンドに提供しないことです。これは、のpygraphvizdocstringに記載されていることがわかります。ところで、それは引数と同じことをします。ソースを見ると、pygraphvizはgraphvizを呼び出してレイアウトを生成します。progdrawlayoutdrawprog="neato"-n2

于 2021-02-10T16:25:29.807 に答える