简体   繁体   English

如何从左到右画树

[英]How to draw trees left to right

Consider the tree below.考虑下面的树。

import matplotlib.pyplot as plt
import networkx as nx
import pydot
from networkx.drawing.nx_pydot import graphviz_layout

T = nx.balanced_tree(2, 5)

for line in nx.generate_adjlist(T):
    print(line)

pos = graphviz_layout(T, prog="dot")
nx.draw(T, pos, node_color="y", edge_color='#909090', node_size=200, with_labels=True)

plt.show()

在此处输入图像描述

How can I draw this left to right so that the whole image is rotated by 90 degrees with the root on the right?如何从左到右绘制,以便整个图像旋转 90 度,根在右侧?

You can do this with the rankdir attribute from graphviz, which can be set on a networkx graph by:您可以使用 graphviz 中的rankdir属性来执行此操作,该属性可以通过以下方式在 networkx 图上设置:

T.graph["graph"] = dict(rankdir="RL")

networkx issue #3547 gives some more info about setting graph attributes. networkx issue #3547提供了有关设置图形属性的更多信息。

If you want to have fine-grained control over node positions (which includes rotating the whole graph) you can actually set each node's position explicitly.如果您想对节点位置进行细粒度控制(包括旋转整个图形),您实际上可以显式设置每个节点的 position。 Here's a way to do that that produces a 'centred' hierarchy, left to right.这是一种产生“中心”层次结构的方法,从左到右。

import itertools
import matplotlib.pyplot as plt
import networkx as nx

plt.figure(figsize=(12,8))
subset_sizes = [1, 2, 4, 8, 16, 32]


def multilayered_graph(*subset_sizes):
    extents = nx.utils.pairwise(itertools.accumulate((0,) + subset_sizes))
    layers = [range(start, end) for start, end in extents]
    G = nx.Graph()
    for (i, layer) in enumerate(layers):
      G.add_nodes_from(layer, layer=i)
    for layer1, layer2 in nx.utils.pairwise(layers):
      G.add_edges_from(itertools.product(layer1, layer2))
    return G

# Instantiate the graph
G = multilayered_graph(*subset_sizes)
# use the multipartite layout
pos = nx.multipartite_layout(G, subset_key="layer")
nodes = G.nodes
nodes_0  = set([n for n in nodes if  G.nodes[n]['layer']==0])
nodes_1  = set([n for n in nodes if  G.nodes[n]['layer']==1])
nodes_2  = set([n for n in nodes if  G.nodes[n]['layer']==2])
nodes_3  = set([n for n in nodes if  G.nodes[n]['layer']==3])
nodes_4  = set([n for n in nodes if  G.nodes[n]['layer']==4])
nodes_5  = set([n for n in nodes if  G.nodes[n]['layer']==5])

# setup a position list
pos = dict()
base = 128
thisList = list(range(-int(base/2),int(base/2),1))
# then assign nodes to indices
pos.update( (n, (10, thisList[int(base/2)::int(base/2)][i])) for i, n in enumerate(nodes_0) )
pos.update( (n, (40, thisList[int(base/4)::int(base/2)][i])) for i, n in enumerate(nodes_1) )
pos.update( (n, (60, thisList[int(base/8)::int(base/4)][i])) for i, n in enumerate(nodes_2) )
pos.update( (n, (80, thisList[int(base/16)::int(base/8)][i])) for i, n in enumerate(nodes_3) )
pos.update( (n, (100, thisList[int(base/32)::int(base/16)][i])) for i, n in enumerate(nodes_4) )
pos.update( (n, (120, thisList[int(base/64)::int(base/32)][i])) for i, n in enumerate(nodes_5) )
nx.draw(G, pos, node_color='y', edge_color='grey', with_labels=True)
plt.show()

在此处输入图像描述

By using a position list, you can easily transform this graph into any number of alignments or rotations.通过使用 position 列表,您可以轻松地将此图转换为任意数量的对齐或旋转。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM