简体   繁体   中英

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?

You can do this with the rankdir attribute from graphviz, which can be set on a networkx graph by:

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

networkx issue #3547 gives some more info about setting graph attributes.

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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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