# 【3.5.2】基于bioptyhon绘制进化树

## 一、初识tree的结构

cat simple.dnd

(((A,B),(C,D)),(E,F,G));


from Bio import Phylo

print(tree)


Tree(rooted=False, weight=1.0)


Tree 对象包含树的全局信息，如树是有根树还是无根树。它包含一个根进化枝， 和以此往下以列表嵌套的所有进化枝，直至叶子分支。

## 二、绘制tree

### 2.1 基本绘制

Phylo.draw_ascii(tree)


                                                    ________________________ A
________________________|
|                        |________________________ B
________________________|
|                        |                         ________________________ C
|                        |________________________|
_|                                                 |________________________ D
|
|                         ________________________ E
|                        |
|________________________|________________________ F
|
|________________________ G


tree.rooted = True
Phylo.draw(tree)


### 2.2 给树的分支上颜色

tree = tree.as_phyloxml()


from Bio.Phylo.PhyloXML import Phylogeny
tree = Phylogeny.from_tree(tree)


tree.root.color = (128, 128, 128)


tree.root.color = "#808080"


tree.root.color = "gray"


mrca = tree.common_ancestor({"name": "E"}, {"name": "F"})
mrca.color = "salmon"


tree.clade[0,1].color = "blue"


Phylo.draw(tree)


result_phyloxml = 'result_phyloxml'
Phylo.write(tree, result_phyloxml, "phyloxml")


result_phyloxml结果如下：

<phyloxml xmlns="http://www.phyloxml.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.phyloxml.org http://www.phyloxml.org/1.10/phyloxml.xsd">
<phylogeny rooted="true">
<color>
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
<name>A</name>
<name>B</name>


## 三、I/O 函数

from Bio import Phylo
print tree


trees = Phylo.parse("Tests/PhyloXML/phyloxml_examples.xml", "phyloxml")
for tree in trees:
print tree


>>> trees = list(Phylo.parse("phyloxml_examples.xml", "phyloxml"))
>>> tree1 = trees[0]
>>> others = trees[1:]
>>> Phylo.write(tree1, "tree1.xml", "phyloxml")
1
>>> Phylo.write(others, "other_trees.xml", "phyloxml")
12


>>> Phylo.convert("tree1.dnd", "newick", "tree1.xml", "nexml")
1
>>> Phylo.convert("other_trees.xml", "phyloxml", "other_trees.nex", 'nexus")
12


>>> from Bio import Phylo
>>> from StringIO import StringIO
>>> handle = StringIO("(((A,B),(C,D)),(E,F,G));")


## 四、查看和导出树

>>> tree = Phylo.read("Tests/PhyloXML/example.xml", "phyloxml")
>>> print tree
Phylogeny(rooted='True', description='phyloXML allows to use either a "branch_length"
attribute...', name='example from Prof. Joe Felsenstein's book "Inferring Phyl...')


>>> tree = Phylo.read("example.xml", "phyloxml")
>>> Phylo.draw_ascii(tree)
__________________ A
__________|
_|          |___________________________________________ B
|
|___________________________________________________________________________ C


draw 函数则使用matplotlib类库画出一个更加好看的图像。查看API文档以获得关于它所接受的 用来定制输出的参数。

>>> tree = Phylo.read("example.xml", "phyloxml")
>>> Phylo.draw(tree, branch_labels=lambda c: c.branch_length)


draw_graphviz 则画出一个无根的进化分枝图（cladogram），但是它要求你安装有Graphviz、 PyDot或PyGraphviz、Network和matplotlib（或pylab）。使用上面相同的例子，和Graphviz中的 dot 程序，让我们来画一个有根树（见图. 13.3 ）：

>>> tree = Phylo.read("example.xml", "phyloxml")
>>> Phylo.draw_graphviz(tree, prog='dot')
>>> import pylab
>>> pylab.show()                    # Displays the tree in an interactive viewer
>>> pylab.savefig('phylo-dot.png')  # Creates a PNG file of the same graphic


（提示：如果你使用 -pylab 选项执行IPython，调用 draw_graphviz 将导致matplotlib 查看器自动运行，而不需要手动的调用 show() 方法。）

>>> tree = Phylo.read("simple.dnd", "newick")
>>> tree.rooted = True
>>> Phylo.draw_graphiz(tree)


## 五、我的案例

### 5.1 继续序列，生成进化树，并对某些选中的序列名进行颜色标记

def build_pho(fasta_file,mark_color_fp,phy_png='tree.png',phy_html='tree.html'):
max_seqname_len = 30
mark_colors = {}
if os.path.exists(mark_color_fp):
with open(mark_color_fp) as data1:
for each_line in data1:
if each_line.strip() == '':
continue
mark_colors[each_line.strip()[:max_seqname_len]] = 'red'
else:
mark_colors = {}

aln_file = '.'.join(fasta_file.split('.')[:-1]) + '.aln'
# mutiple sequence alignment using clustalw2
stdout, stderr = cline()  # run clustalw2, will generate aln_file.  clustalw2 max_seqname_len = 30

# generate tree from identity of alignment
calculator = DistanceCalculator('identity')  # identity
# calculator = DistanceCalculator('blosum62')  # similarity
constructor = DistanceTreeConstructor(calculator, 'upgma')
tree = constructor.build_tree(aln)
clade.name = ''  # get rid of the "inner" names added automatically
print(tree)

# draw phylo plot
n_terms = tree.count_terminals()  # number of terminals to show
height = int(n_terms / 3) + 5  # height grows with number of seqs
# pylab.rcParams['figure.figsize'] = (15.0, height)  # scalable figure size
plt.rcParams['figure.figsize'] = (20.0, height)  # scalable figure size
plt.rcParams["lines.linewidth"] = 1
plt.rcParams["font.size"] = 12   # scalable figure size
Phylo.draw(tree, do_show=False, branch_labels=lambda c: "%.2f%%" % (float(c.branch_length) * 100),
label_colors=mark_colors)  # label format
plt.savefig(phy_png)