示例#1
0
def render(root_node, img, hide_root=False):
    '''main render function. hide_root option is used when render
    trees as Faces

    '''
    mode = img.mode
    orientation = img.orientation

    arc_span = img.arc_span

    layout_fn = img._layout_handler

    parent = _TreeItem()
    n2i = parent.n2i # node to items
    n2f = parent.n2f # node to faces

    parent.bg_layer =  _EmptyItem(parent)
    parent.tree_layer = _EmptyItem(parent)
    parent.float_layer = _EmptyItem(parent)
    parent.float_behind_layer = _EmptyItem(parent)

    TREE_LAYERS = [parent.bg_layer, parent.tree_layer,
                   parent.float_layer, parent.float_behind_layer]

    parent.bg_layer.setZValue(0)
    parent.tree_layer.setZValue(2)

    parent.float_behind_layer.setZValue(1)
    parent.float_layer.setZValue(3)

    # This could be used to handle aligned faces in internal
    # nodes.
    virtual_leaves = 0

    if img.show_branch_length:
        bl_face = faces.AttrFace("dist", fsize=8, ftype="Arial", fgcolor="black", formatter = "%0.3g")
    if img.show_branch_support:
        su_face = faces.AttrFace("support", fsize=8, ftype="Arial", fgcolor="darkred", formatter = "%0.3g")
    if img.show_leaf_name:
        na_face = faces.AttrFace("name", fsize=10, ftype="Arial", fgcolor="black")
    
    for n in root_node.traverse(is_leaf_fn=_leaf):
        set_style(n, layout_fn)

        if img.show_branch_length:
            faces.add_face_to_node(bl_face, n, 0, position="branch-top")

        if not _leaf(n) and img.show_branch_support:
            faces.add_face_to_node(su_face, n, 0, position="branch-bottom")

        if _leaf(n) and n.name and img.show_leaf_name:
            faces.add_face_to_node(na_face, n, 0, position="branch-right")

        if _leaf(n):# or len(n.img_style["_faces"]["aligned"]):
            virtual_leaves += 1

        update_node_faces(n, n2f, img)

    rot_step = float(arc_span) / virtual_leaves
    #rot_step = float(arc_span) / len([n for n in root_node.traverse() if _leaf(n)])

    # Calculate optimal branch length
    if img._scale is not None:
        init_items(root_node, parent, n2i, n2f, img, rot_step, hide_root)
    elif img.scale is None:
        # create items and calculate node dimensions skipping branch lengths
        init_items(root_node, parent, n2i, n2f, img, rot_step, hide_root)
        if mode == 'r':
            if img.optimal_scale_level == "full":
                scales = [(i.widths[1]/n.dist) for n,i in n2i.iteritems() if n.dist]
                img._scale = max(scales) if scales else 0.0
            else:
                farthest, dist = root_node.get_farthest_leaf(topology_only=img.force_topology)
                img._scale = img.tree_width / dist if dist else 0.0
            update_branch_lengths(root_node, n2i, n2f, img)
        else:
            img._scale = crender.calculate_optimal_scale(root_node, n2i, rot_step, img)
            #print "OPTIMAL circular scale", img._scale
            update_branch_lengths(root_node, n2i, n2f, img)
            init_items(root_node, parent, n2i, n2f, img, rot_step, hide_root)
    else:
        # create items and calculate node dimensions CONSIDERING branch lengths
        img._scale = img.scale
        init_items(root_node, parent, n2i, n2f, img, rot_step, hide_root)
        
    #print "USING scale", img._scale
    # Draw node content
    for node in root_node.traverse(is_leaf_fn=_leaf):
        if node is not root_node or not hide_root:
            render_node_content(node, n2i, n2f, img)

    # Adjust content to rect or circular layout
    mainRect = parent.rect()

    if mode == "c":
        tree_radius = crender.render_circular(root_node, n2i, rot_step)
        mainRect.adjust(-tree_radius, -tree_radius, tree_radius, tree_radius)
    else:
        iwidth = n2i[root_node].fullRegion.width()
        iheight = n2i[root_node].fullRegion.height()
        mainRect.adjust(0, 0, iwidth, iheight)
        tree_radius = iwidth

    # Add extra layers: aligned faces, floating faces, node
    # backgrounds, etc. The order by which the following methods are
    # called IS IMPORTANT
    render_floatings(n2i, n2f, img, parent.float_layer, parent.float_behind_layer)

    aligned_region_width = render_aligned_faces(img, mainRect, parent.tree_layer, n2i, n2f)

    render_backgrounds(img, mainRect, parent.bg_layer, n2i, n2f)

    # rotate if necessary in circular images. flip and adjust if mirror orientation. 
    adjust_faces_to_tranformations(img, mainRect, n2i, n2f, TREE_LAYERS)

    # Rotate main image if necessary
    parent.setRect(mainRect)
    parent.setPen(QtGui.QPen(QtCore.Qt.NoPen))

    if img.rotation:
        rect = parent.boundingRect()
        x =  rect.x() + (rect.width()/2.0)
        y =  rect.y() +  (rect.height()/2.0)
        parent.setTransform(QtGui.QTransform().translate(x, y).rotate(img.rotation).translate(-x, -y))

    # Creates the main tree item that will act as frame for the whole image
    frame = QtGui.QGraphicsRectItem()
    parent.setParentItem(frame)
    mainRect = parent.mapToScene(mainRect).boundingRect()

    mainRect.adjust(-img.margin_left, -img.margin_top, \
                         img.margin_right, img.margin_bottom)

    # Fix negative coordinates, so main item always starts at 0,0
    topleft  = mainRect.topLeft()
    _x = abs(topleft.x()) if topleft.x() < 0 else 0
    _y = abs(topleft.y()) if topleft.y() < 0 else 0
    if _x or _y:
        parent.moveBy(_x, _y)
        mainRect.adjust(_x, _y, _x, _y)
        
    # Add extra components and adjust mainRect to them
    add_legend(img, mainRect, frame)
    add_title(img, mainRect, frame)
    add_scale(img, mainRect, frame)
    frame.setRect(mainRect)

    # Draws a border around the tree
    if not img.show_border:
        frame.setPen(QtGui.QPen(QtCore.Qt.NoPen))
    else:
        frame.setPen(QtGui.QPen(QtGui.QColor("black")))
    
    return frame, n2i, n2f
示例#2
0
def render(root_node, img, hide_root=False):
    '''main render function. hide_root option is used when render
    trees as Faces

    '''
    mode = img.mode
    orientation = img.orientation

    arc_span = img.arc_span

    layout_fn = img._layout_handler

    parent = _TreeItem()
    n2i = parent.n2i # node to items
    n2f = parent.n2f # node to faces

    parent.bg_layer =  _EmptyItem(parent)
    parent.tree_layer = _EmptyItem(parent)
    parent.float_layer = _EmptyItem(parent)
    parent.float_behind_layer = _EmptyItem(parent)

    TREE_LAYERS = [parent.bg_layer, parent.tree_layer,
                   parent.float_layer, parent.float_behind_layer]

    parent.bg_layer.setZValue(0)
    parent.tree_layer.setZValue(2)

    parent.float_behind_layer.setZValue(1)
    parent.float_layer.setZValue(3)

    # This could be used to handle aligned faces in internal
    # nodes.
    virtual_leaves = 0

    if img.show_branch_length:
        bl_face = faces.AttrFace("dist", fsize=8, ftype="Arial", fgcolor="black", formatter = "%0.3g")
    if img.show_branch_support:
        su_face = faces.AttrFace("support", fsize=8, ftype="Arial", fgcolor="darkred", formatter = "%0.3g")
    if img.show_leaf_name:
        na_face = faces.AttrFace("name", fsize=10, ftype="Arial", fgcolor="black")
    
    for n in root_node.traverse(is_leaf_fn=_leaf):
        set_style(n, layout_fn)

        if img.show_branch_length:
            faces.add_face_to_node(bl_face, n, 0, position="branch-top")

        if not _leaf(n) and img.show_branch_support:
            faces.add_face_to_node(su_face, n, 0, position="branch-bottom")

        if _leaf(n) and img.show_leaf_name:
            faces.add_face_to_node(na_face, n, 0, position="branch-right")

        if _leaf(n):# or len(n.img_style["_faces"]["aligned"]):
            virtual_leaves += 1

        update_node_faces(n, n2f, img)

    rot_step = float(arc_span) / virtual_leaves
    #rot_step = float(arc_span) / len([n for n in root_node.traverse() if _leaf(n)])

    # Calculate optimal branch length
    if img._scale is not None:
        init_items(root_node, parent, n2i, n2f, img, rot_step, hide_root)
    elif img.scale is None:
        # create items and calculate node dimensions skipping branch lengths
        init_items(root_node, parent, n2i, n2f, img, rot_step, hide_root)
        if mode == 'r':
            if img.optimal_scale_level == "full":
                scales = [(i.widths[1]/n.dist) for n,i in n2i.iteritems() if n.dist]
                img._scale = max(scales) if scales else 0.0
            else:
                farthest, dist = root_node.get_farthest_leaf(topology_only=img.force_topology)
                img._scale = img.tree_width / dist if dist else 0.0
            update_branch_lengths(root_node, n2i, n2f, img)
        else:
            img._scale = crender.calculate_optimal_scale(root_node, n2i, rot_step, img)
            #print "OPTIMAL circular scale", img._scale
            update_branch_lengths(root_node, n2i, n2f, img)
            init_items(root_node, parent, n2i, n2f, img, rot_step, hide_root)
    else:
        # create items and calculate node dimensions CONSIDERING branch lengths
        img._scale = img.scale
        init_items(root_node, parent, n2i, n2f, img, rot_step, hide_root)
        
    #print "USING scale", img._scale
    # Draw node content
    for node in root_node.traverse(is_leaf_fn=_leaf):
        if node is not root_node or not hide_root:
            render_node_content(node, n2i, n2f, img)

    # Adjust content to rect or circular layout
    mainRect = parent.rect()

    if mode == "c":
        tree_radius = crender.render_circular(root_node, n2i, rot_step)
        mainRect.adjust(-tree_radius, -tree_radius, tree_radius, tree_radius)
    else:
        iwidth = n2i[root_node].fullRegion.width()
        iheight = n2i[root_node].fullRegion.height()
        mainRect.adjust(0, 0, iwidth, iheight)
        tree_radius = iwidth

    # Add extra layers: aligned faces, floating faces, node
    # backgrounds, etc. The order by which the following methods are
    # called IS IMPORTANT
    render_floatings(n2i, n2f, img, parent.float_layer, parent.float_behind_layer)

    aligned_region_width = render_aligned_faces(img, mainRect, parent.tree_layer, n2i, n2f)

    render_backgrounds(img, mainRect, parent.bg_layer, n2i, n2f)

    # rotate if necessary in circular images. flip and adjust if mirror orientation. 
    adjust_faces_to_tranformations(img, mainRect, n2i, n2f, TREE_LAYERS)

    # Rotate main image if necessary
    parent.setRect(mainRect)
    parent.setPen(QtGui.QPen(QtCore.Qt.NoPen))

    if img.rotation:
        rect = parent.boundingRect()
        x =  rect.x() + (rect.width()/2.0)
        y =  rect.y() +  (rect.height()/2.0)
        parent.setTransform(QtGui.QTransform().translate(x, y).rotate(img.rotation).translate(-x, -y))

    # Creates the main tree item that will act as frame for the whole image
    frame = QtGui.QGraphicsRectItem()
    parent.setParentItem(frame)
    mainRect = parent.mapToScene(mainRect).boundingRect()

    mainRect.adjust(-img.margin_left, -img.margin_top, \
                         img.margin_right, img.margin_bottom)

    # Fix negative coordinates, so main item always starts at 0,0
    topleft  = mainRect.topLeft()
    _x = abs(topleft.x()) if topleft.x() < 0 else 0
    _y = abs(topleft.y()) if topleft.y() < 0 else 0
    if _x or _y:
        parent.moveBy(_x, _y)
        mainRect.adjust(_x, _y, _x, _y)
        
    # Add extra components and adjust mainRect to them
    add_legend(img, mainRect, frame)
    add_title(img, mainRect, frame)
    add_scale(img, mainRect, frame)
    frame.setRect(mainRect)

    # Draws a border around the tree
    if not img.show_border:
        frame.setPen(QtGui.QPen(QtCore.Qt.NoPen))
    else:
        frame.setPen(QtGui.QPen(QtGui.QColor("black")))
    
    return frame, n2i, n2f
示例#3
0
文件: qt4_render.py 项目: xguse/ete
def set_node_size(node, n2i, n2f, img):
    scale = img.scale
    min_separation = img.min_leaf_separation

    item = n2i[node]
    if img.force_topology:
        branch_length = item.branch_length = float(scale)
    else:
        branch_length = item.branch_length = float(node.dist * scale)

    # Organize faces by groups
    faceblock = update_node_faces(node, n2f, img)
    aligned_height = 0
    if _leaf(node):
        if img.mode == "r": 
            aligned_height = faceblock["aligned"].h
        elif img.mode == "c":
            # aligned faces in circular mode are adjusted afterwords. The
            # min radius of the largest aligned faces will be calculated.
            pass
    
    # Total height required by the node. I cannot sum up the height of
    # all elements, since the position of some of them are forced to
    # be on top or at the bottom of branches. This fact can produce
    # and unbalanced nodeRegion center. Here, I only need to know
    # about the imbalance size to correct node height. The center will
    # be calculated later according to the parent position.
    top_half_h = ( (node.img_style["size"]/2) +
                       node.img_style["hz_line_width"]/2 +
                       faceblock["branch-top"].h )

    bottom_half_h =( (node.img_style["size"]/2) +
                       node.img_style["hz_line_width"]/2 +
                       faceblock["branch-bottom"].h )

    h1 = top_half_h + bottom_half_h
    h2 = max(faceblock["branch-right"].h, \
                 aligned_height, \
                min_separation )
    h = max(h1, h2)
    imbalance = abs(top_half_h - bottom_half_h)
    if imbalance > h2/2:
        h += imbalance - (h2/2)

    # This adds a vertical margin around the node elements
    h += img.branch_vertical_margin
    
    # Total width required by the node
    w = sum([max(branch_length + node.img_style["size"], 
                 faceblock["branch-top"].w + node.img_style["size"],
                 faceblock["branch-bottom"].w + node.img_style["size"],
                 ), 
             faceblock["branch-right"].w]
            )
    w += node.img_style["vt_line_width"]

    # rightside faces region
    item.facesRegion.setRect(0, 0, faceblock["branch-right"].w, h)

    # Node region 
    item.nodeRegion.setRect(0, 0, w, h)

    # This is the node total region covered by the node
    item.fullRegion.setRect(0, 0, w, h)