python - 如何制作具有多个根树的圆形树
问题描述
Radial Positions algorithm
使用从this question转换为python的C ,我已经成功地创建了一个基于根节点的径向图,一直到每个节点的最后一个子节点。现在我有一个新问题,我有多个根节点,需要它们以找到的第一个根为中心,或者至少是一个中心点。
我发现的最接近的例子是这张图:
到目前为止,我所能想到的只是对于找到的每个根节点,将其乘以它的索引,然后将 x 位置与 ay 半径相加。到目前为止,它的效果并不好,因为我的子节点不遵循它。我已经为此困扰了几天。
def RadialPositions(node, id):
children_in_node = len(timelinedatta.neighbors(id, mode="out"))
def rotate_node(x, y, nangle):
nx = x * math.cos(nangle) - y * math.sin(nangle)
ny = x * math.sin(nangle) + y * math.cos(nangle)
return nx, ny
def get_depth(id):
count = 0
for v in timelinedatta.bfsiter(id, mode="in", advanced=True):
count = count + 1
return count - 1
if len(timelinedatta.neighbors(id, mode="out")) > 0 and len(timelinedatta.neighbors(id, mode="in")) == 0:
node["positions"] = (0, 0)
node["depth"] = get_depth(id)
node_children_list = []
for child in timelinedatta.neighbors(id, mode="out"):
node_children_list.append((child, timelinedatta.vs[child]))
for idx, (child_node_id, child_node) in enumerate(node_children_list, start=0):
centerAdjust = 0
if timelinedatta.neighbors(id, mode="in"):
centerAdjust = (-node["angleRange"] + node["angleRange"] / children_in_node) / 2
child_node["depth"] = get_depth(child_node_id)
child_depth = child_node["depth"]
child_node["nodeAngle"] = node["nodeAngle"] + node["angleRange"] / children_in_node * idx + centerAdjust
child_node["angleRange"] = node["angleRange"] / children_in_node
nx = rotate_node(40 * child_depth, 0, child_node["nodeAngle"])[0]
ny = rotate_node(40 * child_depth, 0, child_node["nodeAngle"])[1]
child_node["positions"] = [2 * nx, 2 * ny]
RadialPositions(child_node, child_node_id)
我在pastebin 上也有我的图表示例
解决方案
您可以将graphviz(如@thoku 所建议的)与neato布局引擎(man neato
)一起使用:
neato使用弹簧模型绘制无向图并减少相关能量(参见Kamada 和 Kawai,Information Processing Letters 31:1,April 1989)。
例如,示例
from graphviz import Digraph
tree = Digraph(engine='neato')
tree.node('root1',"R1")
tree.node('root2',"R2")
tree.node('root3',"R3")
tree.node('root4',"R4")
tree.edge('root1','root2')
tree.edge('root1','root3')
tree.edge('root3','root4')
tree.node('child11',"C11")
tree.node('child12',"C12")
tree.node('child13',"C13")
tree.edge('root1','child11')
tree.edge('root1','child12')
tree.edge('root1','child13')
tree.node('child21',"C21")
tree.node('child22',"C22")
tree.edge('root2','child21')
tree.edge('root2','child22')
tree.node('child31',"C31")
tree.node('child32',"C32")
tree.edge('root3','child31')
tree.edge('root3','child32')
tree.node('child41',"C41")
tree.node('child42',"C42")
tree.node('child43',"C43")
tree.edge('root4','child41')
tree.edge('root4','child42')
tree.edge('root4','child43')
tree.render("tree")
生成以下输出:
推荐阅读
- apache-spark - Pyspark 将 Dataframe 字符串列拆分为多列
- javascript - 获取对象中值的长度
- postgresql - 如何使用 where 子句从存储在 PostgreSQL 中 jsonb 列类型中的 JSON 数组中修改或删除特定的 JSON 对象?
- java - 如何制作剪辑到android中滚动位置的滚动视图?
- javascript - 如何将输入的值插入到其下方的输入中
- ruby-on-rails - 在 docker compose 上运行时无法连接到 rails 应用程序中的数据库
- javascript - 为什么我的 vue 代码没有按预期工作?
- android - 由于 NullPointerException,无法启动活动 ComponentInfo
- c++ - C ++静态继承中的取消引用指针问题?
- javascript - 使用声明模块打字稿向类公开属性