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$
4
  • $\begingroup$ If you're not wedded to using python to visualise your trees, FigTree provides a great alternative. $\endgroup$
    – NatWH
    Dec 19, 2018 at 11:54
  • $\begingroup$ Well, this is what hinders me. I am working with python. $\endgroup$ Dec 20, 2018 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, 2018 at 10:41
  • $\begingroup$ I have edited my question for this. $\endgroup$ Dec 22, 2018 at 20:27

2 Answers 2

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$
2
  • $\begingroup$ This still has not helped me. May be an elaborative answer will help. $\endgroup$ Dec 28, 2018 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$
    – M__
    Dec 28, 2018 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$
1
  • $\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$ Dec 24, 2018 at 7:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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