web-dev-qa-db-ja.com

Graphviz:すべてのノードを最大のものと同じサイズにします

各ノードが必要な最大の幅と高さを使用するように、Digraph呼び出しを構成しようとしています。以下の画像を考えると、各ノードは最初のノードの幅と2番目のノードの高さになります。 fixedsize属性を確認しましたが、適切ではないようです。 fixedsizeがtrueに設定されている場合は、制限を指定する必要があります。可能であれば、これを自動的に決定してもらいたいと思います。必要な最大値は、特定のグラフのノードラベルによって異なり、常に同じであるとは限りません。

enter image description here

サンプルセットアップ:

dot = Digraph(comment="Example 1",
          format='png',
          Edge_attr={'color':'black', 
                     'style':'filled'},
          graph_attr={'fixedsize':'false', 
                      'bgcolor':'transparent'},
          node_attr={'fontname':'bold',
                     'fontsize':'11', 
                     'shape':'sqaure', 
                     'color':'black', 
                     'style':'filled', 
                     'fillcolor':'lightsteelblue3'})

fixedsize:falseの場合、ノードのサイズは、ラベルと画像(存在する場合)を含むために必要な最小の幅と高さによって決定され、マージンはmargin属性で指定されます。幅と高さも、これらのパラメーターの最小値を指定する幅と高さの属性で指定されたサイズと少なくとも同じ大きさである必要があります。 trueの場合、ノードサイズは、width属性とheight属性の値によってのみ指定され、テキストラベルを含むように展開されません。ラベル(マージンあり)がこれらの制限内に収まらない場合は、警告が表示されます。 fixedsize属性がshapeに設定されている場合、width属性とheight属性もノード形状のサイズを決定しますが、ラベルははるかに大きくなる可能性があります。ノードのオーバーラップを回避する場合は、ラベルと形状の両方のサイズが使用されますが、ノードのすべてのエッジはラベルを無視し、ノードの形状にのみ接触します。ラベルが大きすぎる場合、警告は表示されません。

編集:厄介な例ですが、それでも例です。グラフを「gv」形式で作成し、高さと幅を処理して、グラフを再作成しました。

from graphviz import Digraph

dot = Digraph(comment="Example 1",
              format='gv',
              Edge_attr={'color':'brown', 
                         'style':'filled'},
              graph_attr={'rankdir':'LR', 
                          'bgcolor':'transparent'},
              node_attr={'fontsize':'11', 
                         'shape':'sqaure', 
                         'color':'black',
                        'style':'filled',
                        'fillcolor':'antiquewhite'})
# nodes and edges
dot.node('1', 'This is the longest width')
dot.node('2', 'This\nis\nthe\nlargest\nheight')
dot.node('3', 'Small')
dot.edges(['12','23'])

def get_node_max(digraph):
    import re
    heights = [height.split('=')[1] for height in re.findall('height=[0-9.]+', str(digraph))]
    widths = [width.split('=')[1] for width in re.findall('width=[0-9.]+', str(digraph))]
    heights.sort(key=float)
    widths.sort(key=float)  
    return heights[len(heights)-1], widths[len(widths)-1]

params = {'format':'png', 'fixedsize':'false', 'width':'1', 'height':'1'}

params['height'], params['width'] = get_node_max(dot.pipe())


dot = Digraph(comment="Example 1",
              format=params['format'],
              Edge_attr={'color':'brown', 
                         'style':'filled'},
              graph_attr={'rankdir':'LR', 
                          'bgcolor':'transparent'},
              node_attr={'fixedsize':params['fixedsize'],
                         'width':params['width'],
                         'height':params['height'],
                         'fontsize':'11', 
                         'shape':'sqaure', 
                         'color':'black',
                        'style':'filled',
                        'fillcolor':'antiquewhite'})
# nodes and edges
dot.node('1', 'This is the longest width')
dot.node('2', 'This\nis\nthe\nlargest\nheight')
dot.node('3', 'Small')
dot.edges(['12','23'])

dot.render('example-graphviz.gv', view=True)

enter image description here

9
10SecTom

明示的な固定のwidthおよびheightノード属性を追加できます。

node_attr={'fixedsize': 'true',
           'width': '2',
           'height': '1.5',
           ...}

これにより、すべてのノードが同じサイズになります。

もちろん、widthheight ..の「正しい」値を手動で決定する必要があります。

2
Flopp