首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用pydot实现紧凑的图形可视化

使用pydot实现紧凑的图形可视化
EN

Stack Overflow用户
提问于 2021-03-08 15:26:18
回答 1查看 185关注 0票数 0

我想用这样的布局来可视化一个“线性”有向图:

所有的内度和外度都是1(当然,第一个和最后一个除外)。标签的长度不同,所以我不能很容易地计算出有多少个节点可以放在一行或另一行中。到目前为止,我拥有的代码是这样的。

代码语言:javascript
运行
复制
import networkx as nx
from networkx.drawing.nx_pydot import to_pydot

G = nx.DiGraph()
G.add_node("XYZ 1.0")
for i in range(1, 20):
    G.add_node(f'XYZ 1.{i}', style='filled', fillcolor='skyblue')
    G.add_edge(f'XYZ 1.{i-1}', f'XYZ 1.{i}')

# set defaults
G.graph['graph'] = {'rankdir': 'LR'}
G.graph['node'] = {'shape': 'rectangle'}
G.graph['edges'] = {'arrowsize': '4.0'}

pydt = to_pydot(G)
prog = 'dot'
file_name = f'nx_graph_{prog}.png'
pydt.write(file_name, prog=prog, format="png")

到目前为止,我在一个需要在Python docker容器中运行的项目中使用networkx,所以如果可能的话,我想使用pydotNetworkx

在一些graphviz程序中,如果我理解正确的话,我可以设置坐标,但是为了设置坐标,我应该知道框的宽度,以避免框重叠。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-10 03:21:24

我设法找到了一种使用pydot实现这一点的方法。我们可以使用write_dot函数创建一个包含坐标的点文件。回读它,我们可以得到dot程序创建的坐标(以及宽度、高度)。我们可以以某种方式计算新的坐标,并在networkx有向图中修改它们。再次转换为pydot.Dot对象,最后,我们可以使用带有-n选项的neato来创建图形,这样我们就可以使用我们设置的坐标。下面可以看到一个有效的代码。

代码语言:javascript
运行
复制
import networkx as nx
from networkx.drawing.nx_pydot import to_pydot
import pydot
from typing import List

G = nx.DiGraph()
G.add_node(0, label="XYZ 1.0")
for i in range(1, 20):
    G.add_node(i, label=f'XYZ 1.{i}')
    G.add_edge(i - 1, i)

# set defaults
G.graph['graph'] = {'rankdir': 'LR'}
G.graph['node'] = {'shape': 'rectangle'}
G.graph['edges'] = {'arrowsize': '4.0'}

pydt = to_pydot(G)
dot_data = pydt.create_dot()

pydt2 = pydot.graph_from_dot_data(dot_data.decode('utf-8'))[0]


def get_position(node):
    pydot_node = pydt2.get_node(str(node))[0]
    return [float(i) for i in pydot_node.get_attributes().get("pos")[1:-1].split(',')]


def fix_position(position: List, w: float = 1000, shift: float = 80):
    x_orig, y_orig = position
    n = int(x_orig / w)
    y = y_orig - n * shift
    remain_x = x_orig - n * w
    if n % 2 == 0:
        x = remain_x
    else:
        x = w - remain_x
    return x, y


def refresh_coordinates_using_x():
    for node in G.nodes:
        position = get_position(node)
        x, y = fix_position(position)
        pos = f'"{x},{y}!"'
        G.nodes[node]['pos'] = pos


refresh_coordinates_using_x()

pydt3 = to_pydot(G)
file_name = f'nx_graph_neato.png'
pydt3.write(file_name, prog=["neato", "-n"], format="png")

如果要根据宽度计算节点的位置,则需要知道坐标是以点为单位的,宽度是以英寸为单位的。1英寸等于72点。

结果将类似于此。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66525752

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档