0
# Visualization and Output
1
2
TreeSwift provides comprehensive visualization capabilities using matplotlib and various output formats including Newick, Nexus, and indented representations. Support for lineages-through-time plots and tree drawing with customizable styling enables publication-quality phylogenetic visualizations.
3
4
## Capabilities
5
6
### Tree Drawing and Visualization
7
8
Draw trees with extensive customization options for scientific visualization.
9
10
```python { .api }
11
def draw(self, show_plot: bool = True, export_filename: str = None, show_labels: bool = False, align_labels: bool = False, label_fontsize: int = 8, start_time: float = 0, default_color: str = '#000000', xlabel: str = None, handles=None) -> None:
12
"""
13
Draw tree visualization using matplotlib.
14
15
Parameters:
16
- show_plot (bool): Display the plot window
17
- export_filename (str): Save plot to file (format determined by extension)
18
- show_labels (bool): Display node labels
19
- align_labels (bool): Align leaf labels vertically
20
- label_fontsize (int): Font size for labels
21
- start_time (float): Starting time for root
22
- default_color (str): Default color for tree elements
23
- xlabel (str): X-axis label
24
- handles: Custom legend handles
25
"""
26
```
27
28
Usage examples:
29
30
```python
31
import treeswift
32
import matplotlib.pyplot as plt
33
34
# Basic tree drawing
35
tree = treeswift.read_tree_newick("((A:0.1,B:0.2):0.3,(C:0.4,D:0.5):0.6);")
36
37
# Simple tree plot
38
tree.draw(show_labels=True)
39
40
# Customized tree plot
41
tree.draw(
42
show_labels=True,
43
align_labels=True,
44
label_fontsize=12,
45
default_color='blue',
46
xlabel='Branch Length',
47
export_filename='my_tree.png'
48
)
49
50
# Multiple trees on same figure
51
tree1 = treeswift.read_tree_newick("((A,B),(C,D));")
52
tree2 = treeswift.read_tree_newick("(((A,B),C),D);")
53
54
plt.figure(figsize=(12, 6))
55
56
plt.subplot(1, 2, 1)
57
tree1.draw(show_plot=False, show_labels=True)
58
plt.title("Balanced Tree")
59
60
plt.subplot(1, 2, 2)
61
tree2.draw(show_plot=False, show_labels=True)
62
plt.title("Unbalanced Tree")
63
64
plt.tight_layout()
65
plt.show()
66
```
67
68
### Lineages Through Time Analysis
69
70
Analyze and visualize lineage dynamics over time with publication-quality plots.
71
72
```python { .api }
73
def lineages_through_time(self, present_day: float = None, show_plot: bool = True, export_filename: str = None, color: str = '#000000', xmin: float = None, xmax: float = None, ymin: float = None, ymax: float = None, title: str = None, xlabel: str = None, ylabel: str = None) -> dict:
74
"""
75
Compute and optionally plot lineages through time.
76
77
Parameters:
78
- present_day (float): Time point representing present day
79
- show_plot (bool): Display the LTT plot
80
- export_filename (str): Save plot to file
81
- color (str): Plot line color
82
- xmin, xmax (float): X-axis limits
83
- ymin, ymax (float): Y-axis limits
84
- title (str): Plot title
85
- xlabel (str): X-axis label
86
- ylabel (str): Y-axis label
87
88
Returns:
89
- dict: Dictionary mapping times to lineage counts
90
"""
91
92
def ltt(self, **kwargs) -> dict:
93
"""Alias for lineages_through_time with same parameters."""
94
95
def plot_ltt(lineages: dict, show_plot: bool = True, export_filename: str = None, color: str = '#000000', xmin: float = None, xmax: float = None, ymin: float = None, ymax: float = None, title: str = None, xlabel: str = None, ylabel: str = None) -> None:
96
"""
97
Plot lineages through time from precomputed data.
98
99
Parameters:
100
- lineages (dict): Lineages dictionary from lineages_through_time()
101
- show_plot (bool): Display the plot
102
- export_filename (str): Save plot to file
103
- color (str): Plot line color
104
- xmin, xmax (float): X-axis limits
105
- ymin, ymax (float): Y-axis limits
106
- title (str): Plot title
107
- xlabel (str): X-axis label
108
- ylabel (str): Y-axis label
109
"""
110
```
111
112
Usage examples:
113
114
```python
115
import treeswift
116
117
# Basic LTT analysis
118
tree = treeswift.read_tree_newick("((A:0.1,B:0.2):0.3,(C:0.4,D:0.5):0.6);")
119
120
# Generate LTT plot
121
ltt_data = tree.lineages_through_time(
122
show_plot=True,
123
title="Lineages Through Time",
124
xlabel="Time (My)",
125
ylabel="Number of Lineages"
126
)
127
128
print("LTT data points:")
129
for time, lineages in sorted(ltt_data.items()):
130
print(f" Time {time:.3f}: {lineages} lineages")
131
132
# Customized LTT plot
133
tree.ltt(
134
color='red',
135
title='Diversification Pattern',
136
xlabel='Time before present',
137
ylabel='Lineage count',
138
export_filename='ltt_plot.pdf'
139
)
140
141
# Compare multiple trees
142
trees = [
143
treeswift.read_tree_newick("((A:0.1,B:0.1):0.8,(C:0.1,D:0.1):0.8);"), # Early burst
144
treeswift.read_tree_newick("((A:0.8,B:0.8):0.1,(C:0.8,D:0.8):0.1);"), # Late burst
145
]
146
147
colors = ['blue', 'red']
148
labels = ['Early diversification', 'Late diversification']
149
150
plt.figure(figsize=(10, 6))
151
for i, tree in enumerate(trees):
152
ltt_data = tree.lineages_through_time(show_plot=False)
153
treeswift.plot_ltt(
154
ltt_data,
155
show_plot=False,
156
color=colors[i]
157
)
158
159
plt.legend(labels)
160
plt.title('Comparison of Diversification Patterns')
161
plt.xlabel('Time')
162
plt.ylabel('Number of Lineages')
163
plt.show()
164
```
165
166
### Text-based Output Formats
167
168
Generate various text representations of trees for different purposes.
169
170
```python { .api }
171
def newick(self) -> str:
172
"""
173
Generate Newick format string.
174
175
Returns:
176
- str: Standard Newick representation of tree
177
"""
178
179
def indent(self, space: int = 4) -> str:
180
"""
181
Generate indented text representation (like nw_indent).
182
183
Parameters:
184
- space (int): Number of spaces per indentation level
185
186
Returns:
187
- str: Indented tree representation
188
"""
189
```
190
191
Usage examples:
192
193
```python
194
import treeswift
195
196
tree = treeswift.read_tree_newick("((A:0.1,B:0.2):0.3,(C:0.4,D:0.5):0.6);")
197
198
# Standard Newick output
199
newick_str = tree.newick()
200
print("Newick format:")
201
print(newick_str)
202
203
# Indented representation
204
indented = tree.indent(space=2)
205
print("\nIndented format:")
206
print(indented)
207
208
# More readable indentation
209
readable = tree.indent(space=4)
210
print("\nReadable format:")
211
print(readable)
212
213
# Compare formats for complex tree
214
complex_tree = treeswift.read_tree_newick("(((((A,B),C),D),E),((F,G),(H,I)));")
215
print("\nComplex tree - Newick:")
216
print(complex_tree.newick())
217
print("\nComplex tree - Indented:")
218
print(complex_tree.indent())
219
```
220
221
### File Output Operations
222
223
Write trees to various file formats with compression support.
224
225
```python { .api }
226
def write_tree_newick(self, filename: str, hide_rooted_prefix: bool = False) -> None:
227
"""
228
Write tree to Newick format file.
229
230
Parameters:
231
- filename (str): Output filename (.gz extension for compression)
232
- hide_rooted_prefix (bool): Hide rooted tree prefix in output
233
"""
234
235
def write_tree_nexus(self, filename: str) -> None:
236
"""
237
Write tree to Nexus format file.
238
239
Parameters:
240
- filename (str): Output filename (.gz extension for compression)
241
"""
242
```
243
244
Usage examples:
245
246
```python
247
import treeswift
248
import os
249
250
tree = treeswift.read_tree_newick("((A:0.1,B:0.2):0.3,(C:0.4,D:0.5):0.6);")
251
252
# Write to plain text files
253
tree.write_tree_newick("output.nwk")
254
tree.write_tree_nexus("output.nexus")
255
256
# Write to compressed files
257
tree.write_tree_newick("output.nwk.gz")
258
tree.write_tree_nexus("output.nexus.gz")
259
260
# Write with options
261
tree.write_tree_newick("unrooted_format.nwk", hide_rooted_prefix=True)
262
263
# Verify files were created
264
for filename in ["output.nwk", "output.nexus", "output.nwk.gz", "output.nexus.gz"]:
265
if os.path.exists(filename):
266
size = os.path.getsize(filename)
267
print(f"{filename}: {size} bytes")
268
269
# Read back and verify
270
tree_copy = treeswift.read_tree_newick("output.nwk")
271
print(f"Original: {tree.newick()}")
272
print(f"Round-trip: {tree_copy.newick()}")
273
print(f"Identical: {tree.newick() == tree_copy.newick()}")
274
```
275
276
### Advanced Visualization Customization
277
278
Advanced plotting features for specialized visualizations.
279
280
```python { .api }
281
# Additional visualization parameters for draw() method
282
def draw(self,
283
# ... basic parameters ...
284
show_plot: bool = True,
285
export_filename: str = None,
286
# Label options
287
show_labels: bool = False,
288
align_labels: bool = False,
289
label_fontsize: int = 8,
290
# Time and color options
291
start_time: float = 0,
292
default_color: str = '#000000',
293
# Axis options
294
xlabel: str = None,
295
# Legend options
296
handles = None
297
) -> None:
298
"""Extended visualization with advanced customization."""
299
```
300
301
Usage examples:
302
303
```python
304
import treeswift
305
import matplotlib.pyplot as plt
306
import matplotlib.patches as patches
307
308
# Advanced visualization example
309
tree = treeswift.read_tree_newick("((A:0.1,B:0.2):0.3,(C:0.4,D:0.5):0.6);")
310
311
# Create custom visualization
312
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
313
314
# Left plot: Basic visualization
315
plt.sca(ax1)
316
tree.draw(
317
show_plot=False,
318
show_labels=True,
319
align_labels=True,
320
label_fontsize=10,
321
default_color='black'
322
)
323
ax1.set_title('Standard Tree Plot')
324
325
# Right plot: Time-scaled visualization
326
plt.sca(ax2)
327
tree.draw(
328
show_plot=False,
329
show_labels=True,
330
align_labels=True,
331
label_fontsize=10,
332
start_time=1.0, # Root at time 1.0
333
default_color='darkblue',
334
xlabel='Time (Ma)'
335
)
336
ax2.set_title('Time-Scaled Tree')
337
338
plt.tight_layout()
339
plt.show()
340
341
# Export high-quality figure
342
tree.draw(
343
show_labels=True,
344
align_labels=True,
345
label_fontsize=12,
346
default_color='black',
347
xlabel='Evolutionary Distance',
348
export_filename='publication_tree.pdf' # Vector format for publications
349
)
350
351
# Export raster format
352
tree.draw(
353
show_labels=True,
354
export_filename='presentation_tree.png' # Raster format for presentations
355
)
356
```
357
358
### Batch Visualization Operations
359
360
Efficiently create multiple visualizations and comparative plots.
361
362
Usage examples:
363
364
```python
365
import treeswift
366
import matplotlib.pyplot as plt
367
368
# Visualize multiple trees in grid
369
tree_strings = [
370
"((A,B),(C,D));", # Balanced
371
"(((A,B),C),D);", # Unbalanced
372
"(A,B,C,D);", # Star (polytomy)
373
"((A:0.1,B:0.9):0.1,(C:0.5,D:0.5):0.5);" # Mixed branch lengths
374
]
375
376
titles = ['Balanced', 'Unbalanced', 'Star Tree', 'Mixed Branch Lengths']
377
trees = [treeswift.read_tree_newick(s) for s in tree_strings]
378
379
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
380
axes = axes.flatten()
381
382
for i, (tree, title) in enumerate(zip(trees, titles)):
383
plt.sca(axes[i])
384
tree.draw(
385
show_plot=False,
386
show_labels=True,
387
align_labels=True,
388
label_fontsize=8
389
)
390
axes[i].set_title(title)
391
392
plt.tight_layout()
393
plt.savefig('tree_comparison.png', dpi=300, bbox_inches='tight')
394
plt.show()
395
396
# Create LTT comparison
397
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
398
399
# Individual LTT plots
400
for i, tree in enumerate(trees[:2]): # First two trees
401
plt.sca(ax1 if i == 0 else ax2)
402
ltt_data = tree.lineages_through_time(
403
show_plot=False,
404
title=titles[i]
405
)
406
treeswift.plot_ltt(ltt_data, show_plot=False)
407
408
plt.tight_layout()
409
plt.show()
410
```