0
# Tree Visualization and Rendering
1
2
ASCII and Unicode tree rendering with multiple built-in styles for displaying tree structures in console output, documentation, and reports. Provides comprehensive visualization capabilities with customizable formatting.
3
4
## Capabilities
5
6
### RenderTree - Tree Visualization
7
8
Main class for rendering tree structures as formatted text with various styling options, child ordering control, and depth limits.
9
10
```python { .api }
11
class RenderTree:
12
"""
13
Renders tree structure as formatted text.
14
15
Args:
16
node: Root node to render from
17
style: Rendering style (ContStyle, AsciiStyle, etc.)
18
childiter: Function to determine child iteration order
19
maxlevel: Maximum depth to render
20
"""
21
def __init__(self, node, style=ContStyle(), childiter=list, maxlevel=None): ...
22
23
def __str__(self) -> str: ...
24
def __iter__(self) -> Iterator[Row]: ...
25
```
26
27
**Usage Example:**
28
29
```python
30
from anytree import Node, RenderTree, AsciiStyle
31
32
# Create tree structure
33
root = Node("Company")
34
engineering = Node("Engineering", parent=root)
35
marketing = Node("Marketing", parent=root)
36
Node("Backend", parent=engineering)
37
Node("Frontend", parent=engineering)
38
Node("Content", parent=marketing)
39
40
# Basic rendering
41
print(RenderTree(root))
42
# Company
43
# ├── Engineering
44
# │ ├── Backend
45
# │ └── Frontend
46
# └── Marketing
47
# └── Content
48
49
# ASCII-only rendering
50
print(RenderTree(root, style=AsciiStyle()))
51
# Company
52
# |-- Engineering
53
# | |-- Backend
54
# | +-- Frontend
55
# +-- Marketing
56
# +-- Content
57
58
# With max level limit
59
print(RenderTree(root, maxlevel=2))
60
# Company
61
# ├── Engineering
62
# └── Marketing
63
```
64
65
### Rendering Styles
66
67
Multiple built-in styles for different output requirements and character set compatibility.
68
69
#### ContStyle - Unicode Continuous Lines
70
71
Default Unicode style with continuous line characters for modern terminals and documentation.
72
73
```python { .api }
74
class ContStyle(AbstractStyle):
75
"""
76
Unicode tree rendering with continuous lines.
77
"""
78
def __init__(self): ...
79
80
vertical = "│"
81
cont = "├── "
82
end = "└── "
83
```
84
85
#### AsciiStyle - ASCII-Only Characters
86
87
ASCII-compatible style for environments that don't support Unicode characters.
88
89
```python { .api }
90
class AsciiStyle(AbstractStyle):
91
"""
92
ASCII-only tree rendering style.
93
"""
94
def __init__(self): ...
95
96
vertical = "|"
97
cont = "|-- "
98
end = "+-- "
99
```
100
101
#### ContRoundStyle - Unicode Rounded Corners
102
103
Unicode style with rounded corner characters for a softer visual appearance.
104
105
```python { .api }
106
class ContRoundStyle(AbstractStyle):
107
"""
108
Unicode tree rendering with rounded corners.
109
"""
110
def __init__(self): ...
111
112
vertical = "│"
113
cont = "├─ "
114
end = "╰─ "
115
```
116
117
#### DoubleStyle - Double Line Characters
118
119
Unicode style with double-line characters for emphasis and visual distinction.
120
121
```python { .api }
122
class DoubleStyle(AbstractStyle):
123
"""
124
Unicode tree rendering with double lines.
125
"""
126
def __init__(self): ...
127
128
vertical = "║"
129
cont = "╠══ "
130
end = "╚══ "
131
```
132
133
### AbstractStyle - Custom Style Base
134
135
Base class for creating custom rendering styles with user-defined characters.
136
137
```python { .api }
138
class AbstractStyle:
139
"""
140
Tree Render Style base class.
141
142
Args:
143
vertical: Sign for vertical line
144
cont: Chars for a continued branch
145
end: Chars for the last branch
146
"""
147
def __init__(self, vertical, cont, end): ...
148
149
vertical: str
150
cont: str
151
end: str
152
```
153
154
**Usage Example:**
155
156
```python
157
from anytree import Node, RenderTree, AbstractStyle
158
159
# Create custom style
160
class CustomStyle(AbstractStyle):
161
def __init__(self):
162
super().__init__(
163
vertical="▏",
164
cont="▣ ",
165
end="▣ "
166
)
167
168
root = Node("root")
169
Node("child1", parent=root)
170
Node("child2", parent=root)
171
172
print(RenderTree(root, style=CustomStyle()))
173
```
174
175
## Advanced Rendering Features
176
177
### Custom Child Ordering
178
179
Control the order in which child nodes are rendered using the `childiter` parameter:
180
181
```python
182
from anytree import Node, RenderTree
183
184
root = Node("root")
185
Node("zebra", parent=root)
186
Node("apple", parent=root)
187
Node("beta", parent=root)
188
189
# Default order (insertion order)
190
print("Default order:")
191
print(RenderTree(root))
192
193
# Alphabetical order
194
print("\nAlphabetical order:")
195
print(RenderTree(root, childiter=lambda children: sorted(children, key=lambda n: n.name)))
196
197
# Reverse order
198
print("\nReverse order:")
199
print(RenderTree(root, childiter=lambda children: reversed(children)))
200
201
# Custom sorting (by length)
202
print("\nBy name length:")
203
print(RenderTree(root, childiter=lambda children: sorted(children, key=lambda n: len(n.name))))
204
```
205
206
### Depth-Limited Rendering
207
208
Render only a specific number of levels to focus on tree structure or handle very deep trees:
209
210
```python
211
from anytree import Node, RenderTree
212
213
# Create deep tree
214
root = Node("Level 0")
215
current = root
216
for i in range(1, 6):
217
current = Node(f"Level {i}", parent=current)
218
Node(f"Side branch {i}", parent=current)
219
220
# Show only first 3 levels
221
print("First 3 levels:")
222
print(RenderTree(root, maxlevel=3))
223
224
# Show only top 2 levels
225
print("\nTop 2 levels:")
226
print(RenderTree(root, maxlevel=2))
227
```
228
229
### Row-by-Row Processing
230
231
Access individual rendered rows for custom processing or formatting:
232
233
```python
234
from anytree import Node, RenderTree, Row
235
236
root = Node("Company")
237
engineering = Node("Engineering", parent=root)
238
Node("Alice", parent=engineering, role="Engineer")
239
Node("Bob", parent=engineering, role="Manager")
240
241
# Process each row individually
242
for row in RenderTree(root):
243
# row is a Row namedtuple with fields: pre, fill, node
244
indent = row.pre
245
node = row.node
246
fill = row.fill
247
248
# Custom formatting
249
if hasattr(node, 'role'):
250
print(f"{indent}{node.name} ({node.role})")
251
else:
252
print(f"{indent}{node.name}")
253
```
254
255
### Node Information Display
256
257
Include additional node information in rendered output:
258
259
```python
260
from anytree import Node, RenderTree
261
262
class InfoNode(Node):
263
def __init__(self, name, info=None, **kwargs):
264
super().__init__(name, **kwargs)
265
self.info = info
266
267
def __str__(self):
268
if self.info:
269
return f"{self.name} [{self.info}]"
270
return self.name
271
272
root = InfoNode("Company", "Founded 2020")
273
eng = InfoNode("Engineering", "50 employees", parent=root)
274
InfoNode("Backend Team", "Python/Django", parent=eng)
275
InfoNode("Frontend Team", "React/TypeScript", parent=eng)
276
277
print(RenderTree(root))
278
# Company [Founded 2020]
279
# └── Engineering [50 employees]
280
# ├── Backend Team [Python/Django]
281
# └── Frontend Team [React/TypeScript]
282
```
283
284
## Style Comparison
285
286
Here's how the same tree looks with different styles:
287
288
```python
289
from anytree import Node, RenderTree, AsciiStyle, ContStyle, ContRoundStyle, DoubleStyle
290
291
# Create sample tree
292
root = Node("root")
293
child1 = Node("child1", parent=root)
294
child2 = Node("child2", parent=root)
295
Node("grandchild1", parent=child1)
296
Node("grandchild2", parent=child1)
297
Node("grandchild3", parent=child2)
298
299
styles = [
300
("ContStyle (default)", ContStyle()),
301
("AsciiStyle", AsciiStyle()),
302
("ContRoundStyle", ContRoundStyle()),
303
("DoubleStyle", DoubleStyle())
304
]
305
306
for name, style in styles:
307
print(f"\n{name}:")
308
print(RenderTree(root, style=style))
309
```
310
311
**Output:**
312
```
313
ContStyle (default):
314
root
315
├── child1
316
│ ├── grandchild1
317
│ └── grandchild2
318
└── child2
319
└── grandchild3
320
321
AsciiStyle:
322
root
323
|-- child1
324
| |-- grandchild1
325
| +-- grandchild2
326
+-- child2
327
+-- grandchild3
328
329
ContRoundStyle:
330
root
331
├─ child1
332
│ ├─ grandchild1
333
│ ╰─ grandchild2
334
╰─ child2
335
╰─ grandchild3
336
337
DoubleStyle:
338
root
339
╠══ child1
340
║ ╠══ grandchild1
341
║ ╚══ grandchild2
342
╚══ child2
343
╚══ grandchild3
344
```
345
346
## Common Use Cases
347
348
### Documentation Generation
349
350
```python
351
from anytree import Node, RenderTree
352
353
def generate_api_tree(modules):
354
"""Generate API documentation tree"""
355
root = Node("API Documentation")
356
357
for module_name, functions in modules.items():
358
module_node = Node(module_name, parent=root)
359
for func_name in functions:
360
Node(func_name, parent=module_node)
361
362
return RenderTree(root)
363
364
modules = {
365
"authentication": ["login", "logout", "verify_token"],
366
"user_management": ["create_user", "update_user", "delete_user"],
367
"data_processing": ["process_csv", "validate_data"]
368
}
369
370
print(generate_api_tree(modules))
371
```
372
373
### File System Visualization
374
375
```python
376
import os
377
from anytree import Node, RenderTree
378
379
def create_file_tree(path, max_depth=3):
380
"""Create tree representation of file system"""
381
def add_path(parent, path, current_depth):
382
if current_depth >= max_depth:
383
return
384
385
try:
386
for item in os.listdir(path):
387
item_path = os.path.join(path, item)
388
node = Node(item, parent=parent)
389
390
if os.path.isdir(item_path):
391
add_path(node, item_path, current_depth + 1)
392
except PermissionError:
393
pass
394
395
root = Node(os.path.basename(path) or path)
396
add_path(root, path, 0)
397
return RenderTree(root)
398
399
# Visualize current directory structure
400
print(create_file_tree(".", max_depth=2))
401
```
402
403
### Organizational Charts
404
405
```python
406
from anytree import Node, RenderTree
407
408
class Employee(Node):
409
def __init__(self, name, title, parent=None):
410
super().__init__(name, parent=parent)
411
self.title = title
412
413
def __str__(self):
414
return f"{self.name} ({self.title})"
415
416
# Build org chart
417
ceo = Employee("Alice Johnson", "CEO")
418
cto = Employee("Bob Smith", "CTO", parent=ceo)
419
cfo = Employee("Carol Davis", "CFO", parent=ceo)
420
421
Employee("David Wilson", "Senior Engineer", parent=cto)
422
Employee("Eve Brown", "DevOps Engineer", parent=cto)
423
Employee("Frank Miller", "Accountant", parent=cfo)
424
425
print("Organizational Chart:")
426
print(RenderTree(ceo))
427
```