formatting leaf names

1,058 views
Skip to first unread message

pappu

unread,
Apr 7, 2014, 7:47:13 AM4/7/14
to eteto...@googlegroups.com
I am wondering how to change the font color of the leaf name and make it italic or bold. I can only change the node background color with NodeStyle(). Thanks.

Jaime Huerta Cepas

unread,
Apr 7, 2014, 7:56:29 AM4/7/14
to eteto...@googlegroups.com
Use your custom TextFace or AttrFace instances. They both have a fgcolor option to set font color and a tree_style option to set font as italic (not sure if 'bold' is also accepted, this is just a wrapper to qt4 text renderer. You can also try the penwidth option). 

https://pythonhosted.org/ete2/reference/reference_treeview.html#ete2.TextFace

================================================
Jaime Huerta-Cepas, Ph.D.
Structural and Computational Biology Unit
EMBL Heidelberg
Meyerhofstraße 1, 69117 Heidelberg, Germany
http://www.bork.embl.de/~huerta/
================================================


On Mon, Apr 7, 2014 at 1:47 PM, pappu <fraternit...@gmail.com> wrote:
I am wondering how to change the font color of the leaf name and make it italic or bold. I can only change the node background color with NodeStyle(). Thanks.

--
You received this message because you are subscribed to the Google Groups "The ETE toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to etetoolkit+...@googlegroups.com.
To post to this group, send email to eteto...@googlegroups.com.
Visit this group at http://groups.google.com/group/etetoolkit.
For more options, visit https://groups.google.com/d/optout.

pappu

unread,
Apr 7, 2014, 10:11:43 AM4/7/14
to eteto...@googlegroups.com
Thank you for your prompt response. I am trying to selectively change the font color of the leaf names. So far I could only change the background color with the following code:

from ete2 import *

t=Tree("((a,b),c);")
ts = TreeStyle()

ns1 = NodeStyle()
ns1["bgcolor"]="Salmon"

ns2 = NodeStyle()
ns2["bgcolor"]="skyblue"

for node in t.traverse():
if 'b' in node.name:
node.set_style(ns1)
if 'c' in node.name:
node.set_style(ns2)

t.render('tmp1.pdf',tree_style=ts)
t.render('tmp1.svg',tree_style=ts)

Color does not work in the pdf rendering.

Jaime Huerta Cepas

unread,
Apr 9, 2014, 3:15:59 AM4/9/14
to eteto...@googlegroups.com
Leaf names are, using ete2 language, node Faces. AttrFace instances, to be precise. The color and style of the text is not controlled by NodeStyle, but by the Face object itself.

You will need to write your own little layout function in which you create and configure your own node Faces. TextFace and AttrFace accept a fgcolor as argument for the text drawn, while all faces have a bunch of options controlling borders, background color, etc (http://pythonhosted.org/ete2/reference/reference_treeview.html#faces). 

from ete2 import Tree, TreeStyle, faces, AttrFace
def mylayout(node):
    if node.is_leaf():
        nameFace = AttrFace("name", fsize=30, fgcolor='red')
        faces.add_face_to_node(nameFace, node, 0, position="branch-right")
        nameFace.background.color = '#eeeeee'
        nameFace.border.width = 1
t = Tree()
t.populate(10)

ts = TreeStyle()
ts.show_leaf_name = False # disable default leaf name drawing
ts.layout_fn = mylayout # set our custom config
t.show(tree_style=ts)


Check the tutorial and the reference guide, there plenty of examples. 

cheers, 
jaime


================================================
Jaime Huerta-Cepas, Ph.D.
Structural and Computational Biology Unit
EMBL Heidelberg
Meyerhofstraße 1, 69117 Heidelberg, Germany
http://www.bork.embl.de/~huerta/
================================================


Chaim Schramm

unread,
Oct 28, 2015, 3:05:11 PM10/28/15
to The ETE toolkit, hue...@embl.de

You can add support for bold fonts with two additional lines in the TextFace._get_font function:


def _custom_get_font(self):
    font
= QFont(self.ftype, self.fsize)
       
if self.fstyle == "italic":
            font
.setStyle(QFont.StyleItalic)
       
elif self.fstyle == "oblique":
            font
.setStyle(QFont.StyleOblique)
        elif self.fstyle == "bold":
            font
.setBold(True)

   
return font


I currently have this implemented in my code to override the native function provided by ete2:

from ete2.treeview import faces
TextFace._get_font = _my_get_font



and le voila.

~CH

Chaim Schramm

unread,
Oct 28, 2015, 3:06:53 PM10/28/15
to The ETE toolkit, hue...@embl.de
By the way, the penwidth option seems to have no effect for me (at least on text), though I have not investigated closely.

Jaime Huerta Cepas

unread,
Oct 29, 2015, 3:49:11 AM10/29/15
to eteto...@googlegroups.com
thanks Chaim - that's useful. Should go in future updates.

--
Jaime Huerta-Cepas, Ph.D.
Structural and Computational Biology Unit
EMBL-Heidelberg (Germany)

Liza Darrous

unread,
Nov 3, 2015, 9:36:35 AM11/3/15
to The ETE toolkit, fraternit...@gmail.com
I am also wondering about formatting/editing leaf names but not quite like you are. Hope you don't mind me adding my question. 
The tree I'm building becomes very small when linked to alignments and thus it makes the leaf names smaller and difficult to read. To overcome this I've added the following code:

for leaf in tree:
leaf.add_face(AttrFace("name", fsize=50), column=0)

And that's worked wonderfully except the original smaller leaf name still exists next to the new larger one.
I had already written the following command before adding a text face, and still had the leaf name appear in small font:

ts = TreeStyle()
ts.show_leaf_name = False

And now if I set it to True, I get two small font leaf names, and one large one belonging to the text face.
How can I entirely remove everything that isn't the name belonging to the TextFace?

Thank you!

Jaime Huerta Cepas

unread,
Nov 3, 2015, 9:42:22 AM11/3/15
to eteto...@googlegroups.com
you just need to pass the TreeStyle instance that you have just created to the render/show function: 
tree.show(tree_style=ts)



--

Liza Darrous

unread,
Nov 3, 2015, 9:46:43 AM11/3/15
to The ETE toolkit
Oh thanks for the quick reply! I've done that already, forgot to add it in my question but it's the logical thing to do at the end of the code.. What else do you think could work? 
Here's an example of the problem attached, thanks!
TreeCapture.PNG

Jaime Huerta Cepas

unread,
Nov 3, 2015, 9:51:01 AM11/3/15
to eteto...@googlegroups.com
when setting TreeStyle.show_leaf_name to True, a new TextFace is created. When disabled, what you see is what you create and add to the nodes manually. 
I would need to see the whole code snippet to figure out...

Liza Darrous

unread,
Nov 3, 2015, 10:05:05 AM11/3/15
to The ETE toolkit
Well, trying to keep it as short as possible:

from ete2 import PhyloTree, TreeStyle, NodeStyle, TextFace, AttrFace

alg = readFasta(alignFile) #method omitted that reads an alignment file and saves it
phylotree = readFasta(treeStruc) #method omitted that reads a Newick structure file and saves it as well

genetree = PhyloTree(phylotree, alignment=alg, alg_format="fasta")

for leaf in genetree:

lstyle= NodeStyle()
name = leaf.name.split("-")[0]
leaf.add_face(AttrFace("name", fsize=50), column=0)
color = famColor[int(name)]    #dict created but omitted containing different colors for different families, eg '1' => 'Red'
lstyle["bgcolor"] = color
leaf.set_style(lstyle)


ts = TreeStyle()
ts.branch_vertical_margin = 90
ts.show_leaf_name = False
genetree.show(tree_style=ts)

Jaime Huerta Cepas

unread,
Nov 3, 2015, 10:46:14 AM11/3/15
to eteto...@googlegroups.com
it seems that PhyloTree has the name textFace hardcoded. I will fix it asap. 
in the mean time, you can try this workaround, which also allows you to control the size of the sequences...

from ete2 import PhyloTree, TreeStyle, NodeStyle, TextFace, AttrFace, SeqMotifFace, add_face_to_node

def sequence_layout(node):
    if node.is_leaf():
        add_face_to_node(SeqMotifFace(seq=node.sequence, seqtype="aa", height=50, seq_format="seq"), node, column=0, position="aligned")


genetree = PhyloTree(sys.argv[1], alignment=sys.argv[2], alg_format="fasta")

for leaf in genetree:
    lstyle= NodeStyle()
    name = leaf.name.split("-")[0]
    leaf.add_face(AttrFace("name", fsize=50), column=0)
    lstyle["bgcolor"] = 'pink'
    leaf.set_style(lstyle)

ts = TreeStyle()
ts.branch_vertical_margin = 90
ts.show_leaf_name = False
ts.layout_fn = sequence_layout

genetree.show(tree_style=ts)

Liza Darrous

unread,
Nov 3, 2015, 11:22:04 AM11/3/15
to The ETE toolkit
I really really appreciate your help! 
I've tried what you've answered me and while reading it, it seemed very promising, however I did get this error (attached) when I tried your code. Is there something I'm missing, or do I perhaps need a new version update? 
It's normal not to pass a parameter for this method right? (ts.layout_fn = sequence_layout)
ErrorCapture.PNG

Jaime Huerta Cepas

unread,
Nov 5, 2015, 3:26:15 AM11/5/15
to eteto...@googlegroups.com
is the alignment linked to the tree? If so, leaf nodes should have an attribute "node.sequence".
You could also add a check in the layout function, so the SeqMotifFace is only create for nodes with a linked sequence. In example: 
if hasattr(node, "sequence"):
   add_face_to_node(SeqMotifFace(...), .... )

Liza Darrous

unread,
Nov 24, 2015, 1:23:15 AM11/24/15
to The ETE toolkit
Works perfectly! Thank you very much :D 
Reply all
Reply to author
Forward
0 new messages