7
$\begingroup$

I have been using biopython 1.72 to display my phylogenetic tree files.

1)Using the function 'Phylo.draw(pars_tree, branch_labels=lambda c: c.branch_length)' to display branch lengths as well on tree, the tree displays the branch lengths as including all numbers after decimal. While I want the numbers to be truncated to two decimal places. Following is a python method that truncates upto "the number required" decimal places.

def truncate(n, decimals=0):
    multiplier = 10 ** decimals
    return int(n * multiplier) / multiplier
truncate (12.567, 2)  #Using function
12.56                 #Output

Can I use such method with biopython for branch lengths?

2) 'Phylo.draw' function opens the window which is very narrow and if the tree file is larger, all the branches are overlapped and it gets difficult to read what is written. Does anyone know any better display method?

Following is the example code, I have been using:

from Bio import Phylo
from Bio.Phylo.TreeConstruction import *
from Bio import AlignIO

aln = AlignIO.read(open('example.phy'), 'phylip')

calculator = DistanceCalculator()
dm = calculator.get_distance(aln)

constructor = DistanceTreeConstructor()
njtree = constructor.nj(dm)
starting_tree = njtree
scorer = ParsimonyScorer()
searcher = NNITreeSearcher(scorer)
constructor = ParsimonyTreeConstructor(searcher, starting_tree)
pars_tree = constructor.build_tree(aln)
Phylo.draw(pars_tree, branch_labels=lambda c: c.branch_length)

I have an msa file as input and it gives a tree, which looks like:

                                                         _______ Human
                                                 _______|
                                                |       |_______ Chimpanzee
                                         _______|
                                        |       |        _______ Dog
                                 _______|       |_______|
                                |       |               |_______ Cow
                         _______|       |
                        |       |       |_______________________ Elephant
                 _______|       |
                |       |       |_______________________________ Mouse
                |       |
         _______|       |_______________________________________ Platypus
        |       |
        |       |        _______________________________________ Anole_lizard
        |       |_______|
  ______|               |        _______________________________ Chicken
 |      |               |_______|
 |      |                       |_______________________________ Zebra_finch
 |      |
 |      |_______________________________________________________ Xenopus
_|
 |       _______________________________________________________ Zebrafish
 |______|
 |      |_______________________________________________________ Fugu
 |
 |______________________________________________________________ Amphioxus
$\endgroup$
  • $\begingroup$ If you're not wedded to using python to visualise your trees, FigTree provides a great alternative. $\endgroup$ – NatWH Dec 19 '18 at 11:54
  • $\begingroup$ Well, this is what hinders me. I am working with python. $\endgroup$ – Sidra Younas Dec 20 '18 at 5:23
  • $\begingroup$ Can you provide an example of your input tree? I’d approach this my parsing the treefile itself, truncating the values, writing a new tree, and then plotting that, rather than trying to do it whilst plotting. BioPython’s tree handling is not its strong suit IMO, so for something like this I would probably use ETE3 or Dendropy - those tools may include options for truncating your node/branch values. $\endgroup$ – Joe Healey Dec 22 '18 at 10:41
  • $\begingroup$ I have edited my question for this. $\endgroup$ – Sidra Younas Dec 22 '18 at 20:27
1
$\begingroup$

Apologies, try the following,

allclades = list(pars_tree.find_clades(order='level'))
for i, blength in enumerate(allclades):
        printf(blength=%.2f, blength)

"allclades" is a dictionary rather than a simple array.

If this fails I would examine the allclades data structure either using pprint (directly) or using printStruct via the following code,

>>> d = [{'a1':1, 'a2':2, 'a3':3}, [1,2,3], [{'b1':1, 'b2':2}, {'c1':1}], 'd1', 'd2', 'd3']
>>> printStruct(d)

def printStruct(struc, indent=0):
  if isinstance(struc, dict):
    print '  '*indent+'{'
    for key,val in struc.iteritems():
      if isinstance(val, (dict, list, tuple)):
        print '  '*(indent+1) + str(key) + '=> '
        printStruct(val, indent+2)
      else:
        print '  '*(indent+1) + str(key) + '=> ' + str(val)
    print '  '*indent+'}'
  elif isinstance(struc, list):
    print '  '*indent + '['
    for item in struc:
      printStruct(item, indent+1)
    print '  '*indent + ']'
  elif isinstance(struc, tuple):
    print '  '*indent + '('
    for item in struc:
      printStruct(item, indent+1)
    print '  '*indent + ')'
  else: print '  '*indent + str(struc)

Once you know the structure you unravel it accordingly to get to the branch lengths and then issue a printf command to round them to 2 dp.

Goodluck

$\endgroup$
  • $\begingroup$ This still has not helped me. May be an elaborative answer will help. $\endgroup$ – Sidra Younas Dec 28 '18 at 14:17
  • $\begingroup$ If I get a moment I will reproduce the analysis, but I'm not your superviser (a very low priority indeed). "list" is the key to the answer in conjunction with printf. Unlocking the object from "list" to get to the branch lengths is the key here. $\endgroup$ – Michael G. Dec 28 '18 at 20:40
0
$\begingroup$

The universal coding way to do this is the printf command regardless of language (sprintf is used language depending), for Python this is,

blength = 0.22342
printf("Taxa A, blength=%.2f", blength)

Output

Taxa A, 0.22


The following may be useful to your context:

import numpy
allclades = list(pars_tree.find_clades(order='level'))
for blength in enumerate(allclades):
        printf(blength=%.2f, blength)

Goodluck

$\endgroup$
  • $\begingroup$ It did'nt work for me. First there was a syntax error and when I use it this way: allclades = list(pars_tree.find_clades(order='level')) for blength in enumerate(allclades): print(blength = "%8.2f" % blength) . It says, "TypeError: not all arguments converted during string formatting" Any suggestions? $\endgroup$ – Sidra Younas Dec 24 '18 at 7:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.