我想用这样的布局来可视化一个“线性”有向图:
所有的内度和外度都是1(当然,第一个和最后一个除外)。标签的长度不同,所以我不能很容易地计算出有多少个节点可以放在一行或另一行中。到目前为止,我拥有的代码是这样的。
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
,所以如果可能的话,我想使用pydot
和Networkx
。
在一些graphviz程序中,如果我理解正确的话,我可以设置坐标,但是为了设置坐标,我应该知道框的宽度,以避免框重叠。
发布于 2021-03-10 03:21:24
我设法找到了一种使用pydot实现这一点的方法。我们可以使用write_dot
函数创建一个包含坐标的点文件。回读它,我们可以得到dot
程序创建的坐标(以及宽度、高度)。我们可以以某种方式计算新的坐标,并在networkx
有向图中修改它们。再次转换为pydot.Dot
对象,最后,我们可以使用带有-n
选项的neato
来创建图形,这样我们就可以使用我们设置的坐标。下面可以看到一个有效的代码。
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点。
结果将类似于此。
https://stackoverflow.com/questions/66525752
复制相似问题