Я использую библиотеку pygraphviz для построения графика python, созданного с использованием библиотеки networkx . В целом я очень доволен макетом 'neato'
, который выдает что-то вроде этого:
Теперь мои данные структурированы таким образом, что у меня всегда есть центральный узел, затем набор узлов, которые находятся на расстоянии 1 от центра, и затем другой набор узлов, которые находятся на расстоянии 2 от центра. Под «расстоянием» я подразумеваю количество ссылок до достижения центрального узла. В связи с этим я хотел бы навязать расположение узлов расстояния 1 на окружности фиксированного радиуса от центра, скажем, r=1
, а узлов расстояния 2 - на окружности r=2
. Я прилагаю эскиз для ясности:
До сих пор я пытался подойти к проблеме путем ручного определения положения узлов (это не минимум рабочий пример, это просто для того, чтобы показать мой неудачный подход):
# define distance levels
levels = [0, 1, 2]
# assign a radius to each level
radius = {}
for index, level in enumerate(levels):
radius[level] = index
# assign nodes to each level
nodes = {}
for level in levels:
nodes[level] = [x for x,y in graph.nodes(data=True) if y['level']==level]
# calculate position of nodes on the circumferences
pos = {}
for level in levels:
n_nodes = len(nodes[level])
# divide pi in n_nodes parts to get the angle increment of each node
theta = 2*np.pi/n_nodes
n = 1
for node in nodes[level]:
xPos = radius[level]*np.cos(theta*n)
yPos = radius[level]*np.sin(theta*n)
pos[node] = (xPos, yPos)
n += 1
Проблема этого метода в том, что порядок узлов на окружности больше не определяется графвизом, и поэтому граф на самом деле выглядит ужасно, потому что все стрелки наложены друг на друга и пересекают друг друга: Приятно использовать макет 'neato'
в том, что graphviz решает, куда поместить узлы, чтобы получить, ну, в общем, «аккуратный» график , Поэтому мой вопрос: могу ли я сказать графвизу, чтобы он оставлял узлы на кругах, но все же позволил ему решить, каков наилучший порядок узлов?