Пример #1
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """
        current_x = self.mFooterFrom
        current_y = self.mHeaderHeight + self.mDataHeight + 2 * self.mSeparator

        self.mFooterBoxSize = 30
        self.mNumTicks = 20
        for x in range(len(self.mColourThresholds)):

            e = SVGdraw.rect(current_x,
                             current_y,
                             self.mFooterBoxSize,
                             self.mFooterBoxSize,
                             fill="rgb(%i,%i,%i)" % self.mColours[x],
                             stroke="rgb(%i,%i,%i)" % self.mColours[x])

            self.addElement(e)

            if x % self.mNumTicks == 0:

                e = SVGdraw.line(current_x,
                                 current_y,
                                 current_x,
                                 current_y + self.mFooterBoxSize,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 stroke_width=5)
                self.addElement(e)

                e = SVGdraw.text(current_x,
                                 current_y - self.mFooterBoxSize,
                                 self.mFormatNumberLegend % self.mColourThresholds[
                                     x],
                                 self.mFooterFontSize,
                                 self.mFooterFont,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 text_anchor="start")
                self.addElement(e)

            current_x += self.mFooterBoxSize

        ###########################################################
        if self.mFooter:

            current_y += max(self.mFooterFontSize,
                             self.mMaxBoxSize) + self.mSeparator

            e = SVGdraw.text(self.mPageWidth / 2,
                             current_y + self.mFooterFontSize,
                             self.mFooter,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
Пример #2
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """
        current_x = self.mFooterFrom
        current_y = self.mHeaderHeight + self.mDataHeight + 2 * self.mSeparator

        self.mFooterBoxSize = 30
        self.mNumTicks = 20
        for x in range(len(self.mColourThresholds)):

            e = SVGdraw.rect(current_x,
                             current_y,
                             self.mFooterBoxSize,
                             self.mFooterBoxSize,
                             fill="rgb(%i,%i,%i)" % self.mColours[x],
                             stroke="rgb(%i,%i,%i)" % self.mColours[x])

            self.addElement(e)

            if x % self.mNumTicks == 0:

                e = SVGdraw.line(current_x,
                                 current_y,
                                 current_x,
                                 current_y + self.mFooterBoxSize,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 stroke_width=5)
                self.addElement(e)

                e = SVGdraw.text(current_x,
                                 current_y - self.mFooterBoxSize,
                                 self.mFormatNumberLegend %
                                 self.mColourThresholds[x],
                                 self.mFooterFontSize,
                                 self.mFooterFont,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 text_anchor="start")
                self.addElement(e)

            current_x += self.mFooterBoxSize

        ###########################################################
        if self.mFooter:

            current_y += max(self.mFooterFontSize,
                             self.mMaxBoxSize) + self.mSeparator

            e = SVGdraw.text(self.mPageWidth / 2,
                             current_y + self.mFooterFontSize,
                             self.mFooter,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
Пример #3
0
    def writeRowHeader(self):
        """write row header

        The row header contains the species names
        """
        x = 0
        y = self.mHeaderHeight

        max_l = 0

        for species in self.mSpeciesList:
            max_l = max(max_l,
                        len(species) * self.mHeaderFontSize) * self.mFontFactor
            e = SVGdraw.text(x,
                             y,
                             species,
                             self.mHeaderFontSize,
                             self.mHeaderFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="left")

            self.addElement(e)

            y += self.mBlockSize + self.mHorizontalSeparator

        self.mHeaderWidth = max_l
Пример #4
0
    def addGroupStart(self, x, y, contig, start):
        """plot start of contig."""

        t = "%s:%i" % (contig, start)
        max_x = x + len(t) * self.contigFontSize * self.mFontFactor

        ## plot line
        e = SVGdraw.line(
            x,
            y,
            max_x,
            y,
            stroke="rgb(%i,%i,%i)" % BLACK,
        )

        self.addElement(e)
        e = SVGdraw.text(x,
                         y,
                         t,
                         self.contigFontSize,
                         self.contigFont,
                         stroke="rgb(%i,%i,%i)" % BLACK,
                         text_anchor="left")

        self.addElement(e)

        return max_x
Пример #5
0
    def writeColHeaders(self):
        """write row headers."""

        current_x = self.mColWidth / 2
        current_y = self.mHeaderHeight
        for i in range(len(self.mColNames)):
            if self.mMarkColumns and self.mMarkColumns[i]:
                color = BLUE
                name = self.mColNames[i] + "*"
            else:
                color = BLACK
                name = self.mColNames[i]

            e = SVGdraw.text(current_x,
                             current_y,
                             name,
                             self.mHeaderFontSize,
                             self.mHeaderFont,
                             stroke="rgb(%i,%i,%i)" % color,
                             text_anchor="start",
                             transform="rotate(-45,%i,%i)" %
                             (current_x, current_y))

            self.mElements.append(e)

            current_x += self.mColWidth
Пример #6
0
    def writeColHeaders(self):
        """write row headers."""

        current_x = self.mColWidth / 2
        current_y = self.mHeaderHeight
        for i in range(len(self.mColNames)):
            if self.mMarkColumns and self.mMarkColumns[i]:
                color = BLUE
                name = self.mColNames[i] + "*"
            else:
                color = BLACK
                name = self.mColNames[i]

            e = SVGdraw.text(
                current_x,
                current_y,
                name,
                self.mHeaderFontSize,
                self.mHeaderFont,
                stroke="rgb(%i,%i,%i)" % color,
                text_anchor="start",
                transform="rotate(-45,%i,%i)" % (current_x, current_y))

            self.mElements.append(e)

            current_x += self.mColWidth
Пример #7
0
    def getElements(self, node_id, x1, x2, y):

        e = SVGTree.BranchDecoratorHorizontal.getElements(
            self, node_id, x1, x2, y)

        table_id = str(int(self.mTree.node(node_id).data.branchlength))

        if table_id not in self.mTables:
            return e

        startx = x1 + self.mFontSize
        y = y + self.mFontSize

        table, column_widths = self.mTables[
            table_id], self.mColumnWidths[table_id]

        font_weight = "bold"

        for r, row in enumerate(table):
            x = startx

            for c, col in enumerate(row):
                e.append(SVGdraw.text(x, y,
                                      col,
                                      20,
                                      self.mFont,
                                      stroke="rgb(%i,%i,%i)" % self.mFontColour,
                                      font_weight=font_weight,
                                      text_anchor="left"))
                x += column_widths[c] * self.mFontSize // 2

            y += self.mFontSize
            font_weight = "normal"

        return e
Пример #8
0
    def writeRowHeader(self):
        """write row header

        The row header contains the species names
        """
        x = 0
        y = self.mHeaderHeight

        max_l = 0

        for species in self.mSpeciesList:
            max_l = max(max_l, len(species) * self.mHeaderFontSize) * self.mFontFactor
            e = SVGdraw.text(
                x,
                y,
                species,
                self.mHeaderFontSize,
                self.mHeaderFont,
                stroke="rgb(%i,%i,%i)" % BLACK,
                text_anchor="left",
            )

            self.addElement(e)

            y += self.mBlockSize + self.mHorizontalSeparator

        self.mHeaderWidth = max_l
Пример #9
0
    def writeScale(self):
        """write scales."""

        current_x = self.mScaleX
        current_y = self.mScaleY + self.mScaleHeight

        nboxes = len(self.mColourThresholds)
        # box size for legend in x-direction
        # subtract size of right-most axis label so that it takes the
        # same width as self.mDataWidth.
        box_size_x = math.ceil(
            (self.mDataWidth -
             (self.mScaleFontSize *
              len(self.mFormatNumberLegend % self.mColourThresholds[-1]))) /
            nboxes)

        # change font size such that it labels will fit between tick-marks
        self.mScaleFontSize = min(
            self.mScaleFontSize, (box_size_x * self.mScaleNumTicks * 1.5) /
            len(self.mFormatNumberLegend % self.mColourThresholds[-1]))

        for x in range(nboxes):

            e = SVGdraw.rect(current_x,
                             current_y,
                             box_size_x,
                             self.mScaleBoxSizeY,
                             fill="rgb(%i,%i,%i)" % self.mColours[x],
                             stroke="rgb(%i,%i,%i)" % self.mColours[x])

            self.addElement(e)

            if x % self.mScaleNumTicks == 0:

                e = SVGdraw.line(current_x,
                                 current_y,
                                 current_x,
                                 current_y + self.mScaleBoxSizeY,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 stroke_width=5)
                self.addElement(e)

                e = SVGdraw.text(current_x,
                                 current_y - self.mScaleBoxSizeY,
                                 self.mFormatNumberLegend %
                                 self.mColourThresholds[x],
                                 self.mScaleFontSize,
                                 self.mScaleFont,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 text_anchor="start")
                self.addElement(e)

            current_x += box_size_x
Пример #10
0
    def writeScale(self):
        """write scales."""

        current_x = self.mScaleX
        current_y = self.mScaleY + self.mScaleHeight

        nboxes = len(self.mColourThresholds)
        # box size for legend in x-direction
        # subtract size of right-most axis label so that it takes the
        # same width as self.mDataWidth.
        box_size_x = math.ceil((self.mDataWidth -
                                (self.mScaleFontSize * len(
                                    self.mFormatNumberLegend %
                                    self.mColourThresholds[-1]))) / nboxes)

        # change font size such that it labels will fit between tick-marks
        self.mScaleFontSize = min(self.mScaleFontSize,
                                  (box_size_x * self.mScaleNumTicks * 1.5) /
                                  len(self.mFormatNumberLegend %
                                      self.mColourThresholds[-1]))

        for x in range(nboxes):

            e = SVGdraw.rect(current_x,
                             current_y,
                             box_size_x,
                             self.mScaleBoxSizeY,
                             fill="rgb(%i,%i,%i)" % self.mColours[x],
                             stroke="rgb(%i,%i,%i)" % self.mColours[x])

            self.addElement(e)

            if x % self.mScaleNumTicks == 0:

                e = SVGdraw.line(current_x,
                                 current_y,
                                 current_x,
                                 current_y + self.mScaleBoxSizeY,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 stroke_width=5)
                self.addElement(e)

                e = SVGdraw.text(current_x,
                                 current_y - self.mScaleBoxSizeY,
                                 self.mFormatNumberLegend % self.mColourThresholds[
                                     x],
                                 self.mScaleFontSize,
                                 self.mScaleFont,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 text_anchor="start")
                self.addElement(e)

            current_x += box_size_x
Пример #11
0
    def writeTitle(self):
        """write title into plot."""

        if self.mTitle:
            e = SVGdraw.text(self.mPageWidth / 2,
                             self.mTitleFontSize,
                             self.mTitle,
                             self.mTitleFontSize,
                             self.mTitleFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
Пример #12
0
    def writeTitle(self):
        """write title into plot."""

        if self.mTitle:
            e = SVGdraw.text(self.mPageWidth / 2,
                             self.mTitleFontSize,
                             self.mTitle,
                             self.mTitleFontSize,
                             self.mTitleFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
Пример #13
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """
        if self.mTitle:
            e = SVGdraw.text(self.mPageWidth / 2,
                             self.mTitleFontSize,
                             self.mTitle,
                             self.mTitleFontSize,
                             self.mTitleFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
Пример #14
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """
        if self.mTitle:
            e = SVGdraw.text(self.mPageWidth / 2,
                             self.mTitleFontSize,
                             self.mTitle,
                             self.mTitleFontSize,
                             self.mTitleFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
Пример #15
0
    def getElements(self, node_id, x, y, x_label=None, y_label=None):

        e = NodeDecorator.getElements(self, node_id, x, y)

        if x_label is None:
            x_label = x
        if y_label is None:
            y_label = y
        e.append(SVGdraw.text(x_label, y_label,
                              self.mTree.node(node_id).data.taxon,
                              self.mFontSize,
                              self.mFont,
                              stroke="rgb(%i,%i,%i)" % BLACK,
                              font_style=self.mFontStyle,
                              text_anchor="left"))
        return e
Пример #16
0
    def addGroupStart(self, x, y, contig, start):
        """plot start of contig."""

        t = "%s:%i" % (contig, start)
        max_x = x + len(t) * self.contigFontSize * self.mFontFactor

        # plot line
        e = SVGdraw.line(x, y, max_x, y, stroke="rgb(%i,%i,%i)" % BLACK)

        self.addElement(e)
        e = SVGdraw.text(
            x, y, t, self.contigFontSize, self.contigFont, stroke="rgb(%i,%i,%i)" % BLACK, text_anchor="left"
        )

        self.addElement(e)

        return max_x
Пример #17
0
    def writeGrid(self):
        """add grid lines."""

        middlex = self.mDataMiddleX
        middley = self.mDataMiddleY

        # print separators
        for c in range(len(self.contigs)):

            contig = self.contigs[c]

            pos = self.getPosition(contig, "+", 0)
            angle = self.getAngle(pos)

            x, y = self.getPosOnArc(angle, self.mRadius)

            e = SVGdraw.line(middlex,
                             middley,
                             x,
                             y,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=self.mGridStrokeWidth)

            self.addElement(e, self.mPlaneGrid)

            if c < len(self.contigs) - 1:
                next_angle = self.getAngle(
                    self.getPosition(self.contigs[c + 1], "+", 0))
            else:
                next_angle = 360

            x, y = self.getPosOnArc(
                angle + float(next_angle - angle) / 2, self.mRadiusStart / 2)

            e = SVGdraw.text(x,
                             y,
                             contig,
                             self.mGridFontSize,
                             self.mGridFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start")
            # do not rotate text:
            # transform="rotate(%i,%i,%i)" % ( angle, x, y ))

            self.addElement(e)
Пример #18
0
    def writeGrid(self):
        """add grid lines."""

        middlex = self.mDataMiddleX
        middley = self.mDataMiddleY

        # print separators
        for c in range(len(self.contigs)):

            contig = self.contigs[c]

            pos = self.getPosition(contig, "+", 0)
            angle = self.getAngle(pos)

            x, y = self.getPosOnArc(angle, self.mRadius)

            e = SVGdraw.line(middlex,
                             middley,
                             x,
                             y,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=self.mGridStrokeWidth)

            self.addElement(e, self.mPlaneGrid)

            if c < len(self.contigs) - 1:
                next_angle = self.getAngle(
                    self.getPosition(self.contigs[c + 1], "+", 0))
            else:
                next_angle = 360

            x, y = self.getPosOnArc(
                angle + float(next_angle - angle) / 2, self.mRadiusStart / 2)

            e = SVGdraw.text(x,
                             y,
                             contig,
                             self.mGridFontSize,
                             self.mGridFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start")
            # do not rotate text:
            # transform="rotate(%i,%i,%i)" % ( angle, x, y ))

            self.addElement(e)
Пример #19
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """

        x = self.mHeaderWidth + self.mBlockSize

        group_ids = self.mMapGroup2Colour.keys()
        group_ids.sort()
        ncolumns = 10
        l = int(math.ceil(len(group_ids) / float(ncolumns)))

        max_d = 0

        for a in range(0, ncolumns):

            y = self.mHeaderHeight + self.mDataHeight
            for b in range(a * l, min(len(group_ids), (a + 1) * l)):

                group_id = group_ids[b]

                e = self.plotGene(x, y, group_id=group_id)
                self.addElement(e)

                t = str(group_id)

                max_d = max(
                    len(t) * self.mLegendFontSize * self.mFontFactor, max_d)

                e = SVGdraw.text(x + self.mBlockSize +
                                 self.mLegendVerticalSeparator,
                                 y,
                                 str(group_id),
                                 self.mLegendFontSize,
                                 self.mLegendFont,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 text_anchor="left")

                self.addElement(e)

                y += self.mLegendFontSize + self.mLegendHorizontalSeparator

            x += max_d + 2 * self.mBlockSize + \
                2 * self.mLegendVerticalSeparator
Пример #20
0
    def getElements(self, node_id, x, y, x_label=None, y_label=None):

        e = NodeDecorator.getElements(self, node_id, x, y)

        if x_label is None:
            x_label = x
        if y_label is None:
            y_label = y
        e.append(
            SVGdraw.text(x_label,
                         y_label,
                         self.mTree.node(node_id).data.taxon,
                         self.mFontSize,
                         self.mFont,
                         stroke="rgb(%i,%i,%i)" % BLACK,
                         font_style=self.mFontStyle,
                         text_anchor="left"))
        return e
Пример #21
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """

        x = self.mHeaderWidth + self.mBlockSize

        group_ids = self.mMapGroup2Colour.keys()
        group_ids.sort()
        ncolumns = 10
        l = int(math.ceil(len(group_ids) / float(ncolumns)))

        max_d = 0

        for a in range(0, ncolumns):

            y = self.mHeaderHeight + self.mDataHeight
            for b in range(a * l, min(len(group_ids), (a + 1) * l)):

                group_id = group_ids[b]

                e = self.plotGene(x, y, group_id=group_id)
                self.addElement(e)

                t = str(group_id)

                max_d = max(len(t) * self.mLegendFontSize * self.mFontFactor, max_d)

                e = SVGdraw.text(
                    x + self.mBlockSize + self.mLegendVerticalSeparator,
                    y,
                    str(group_id),
                    self.mLegendFontSize,
                    self.mLegendFont,
                    stroke="rgb(%i,%i,%i)" % BLACK,
                    text_anchor="left",
                )

                self.addElement(e)

                y += self.mLegendFontSize + self.mLegendHorizontalSeparator

            x += max_d + 2 * self.mBlockSize + 2 * self.mLegendVerticalSeparator
Пример #22
0
    def writeColHeaders( self ):
        """write row headers."""

        current_x = self.mColWidth / 2
        current_y = self.mHeaderHeight
        i = 0
        for name in self.mColNames:
            e = SVGdraw.text( current_x,
                              current_y,
                              name,
                              self.mHeaderFontSize,
                              self.mHeaderFont,
                              stroke = "rgb(%i,%i,%i)" % BLACK,
                              text_anchor = "start",
                              transform="rotate(-45,%i,%i)" %( current_x, current_y ))

            self.addElement(e)
            
            current_x += self.mColWidth
Пример #23
0
    def writeColHeaders(self):
        """write row headers."""

        current_x = self.mColWidth / 2
        current_y = self.mHeaderHeight
        i = 0
        for name in self.mColNames:
            e = SVGdraw.text(current_x,
                             current_y,
                             name,
                             self.mHeaderFontSize,
                             self.mHeaderFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start",
                             transform="rotate(-45,%i,%i)" % (current_x, current_y))

            self.addElement(e)

            current_x += self.mColWidth
Пример #24
0
    def writeColLabels( self ):
        """write column headers."""

        y = self.mHeaderHeight

        for contig in self.mSortedContigs1:

            if contig not in self.mMapContig2Start1: continue
            
            x = self.mHeaderWidth + self.mMapContig2Start1[contig] 
            e = SVGdraw.text( x,
                              y,
                              contig,
                              self.mLabelFontSize * self.mFontSizeFactor,
                              self.mLabelFont,
                              stroke = "rgb(%i,%i,%i)" % BLACK,
                              text_anchor = "start" )

            self.addElement( e )
Пример #25
0
    def writeColLabels(self):
        """write column headers."""

        y = self.mHeaderHeight

        for contig in self.mSortedContigs1:

            if contig not in self.mMapContig2Start1: continue

            x = self.mHeaderWidth + self.mMapContig2Start1[contig]
            e = SVGdraw.text(x,
                             y,
                             contig,
                             self.mLabelFontSize * self.mFontSizeFactor,
                             self.mLabelFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start")

            self.addElement(e)
Пример #26
0
    def getElements(self, node_id, x, y, x_label=None, y_label=None):

        e = NodeDecorator.getElements(self, node_id, x, y)

        if x_label is None:
            x_label = x
        if y_label is None:
            y_label = y

        t = self.mTree.node(node_id).data.taxon
        species = self.mExtractSpecies(t)

        if species not in self.mMapSpecies2Colour:
            self.mMapSpecies2Colour[species] = COLOURS[len(
                self.mMapSpecies2Colour) % len(COLOURS)]

        if species in self.mMapSpecies2Name:
            tx = re.sub(species, "%s" % self.mMapSpecies2Name[species], t)
        else:
            tx = t

        colour = self.getColour(node_id, x, y)

        if self.mPlotLabel:
            ee = SVGdraw.text(x_label,
                              y_label,
                              tx,
                              self.mFontSize,
                              self.mFont,
                              stroke="rgb(%i,%i,%i)" % colour,
                              text_anchor="left")

            if self.mMapTaxon2URL is not None:
                url = self.mMapTaxon2URL(t)
                if url:
                    l = SVGdraw.link(url)
                    l.addElement(ee)
                    e.append(l)
                else:
                    e.append(ee)
            else:
                e.append(ee)
        return e
Пример #27
0
    def getElements(self, node_id, x, y, x_label=None, y_label=None):

        e = NodeDecorator.getElements(self, node_id, x, y)

        if x_label is None:
            x_label = x
        if y_label is None:
            y_label = y

        t = self.mTree.node(node_id).data.taxon
        species = self.mExtractSpecies(t)

        if species not in self.mMapSpecies2Colour:
            self.mMapSpecies2Colour[species] = COLOURS[
                len(self.mMapSpecies2Colour) % len(COLOURS)]

        if species in self.mMapSpecies2Name:
            tx = re.sub(species, "%s" % self.mMapSpecies2Name[species], t)
        else:
            tx = t

        colour = self.getColour(node_id, x, y)

        if self.mPlotLabel:
            ee = SVGdraw.text(x_label, y_label,
                              tx,
                              self.mFontSize,
                              self.mFont,
                              stroke="rgb(%i,%i,%i)" % colour,
                              text_anchor="left")

            if self.mMapTaxon2URL is not None:
                url = self.mMapTaxon2URL(t)
                if url:
                    l = SVGdraw.link(url)
                    l.addElement(ee)
                    e.append(l)
                else:
                    e.append(ee)
            else:
                e.append(ee)
        return e
Пример #28
0
    def writeRowLabels( self ):
        """write column headers."""

        x = self.mHeaderWidth
        
        for contig in self.mSortedContigs2:
            
            if contig not in self.mMapContig2Start2: continue
            
            y = self.mHeaderHeight + self.mMapContig2Start2[contig] + self.mMapContig2Size2[contig]
            e = SVGdraw.text( x,
                              y,
                              contig,
                              self.mLabelFontSize * self.mFontSizeFactor,
                              self.mLabelFont,
                              stroke = "rgb(%i,%i,%i)" % BLACK,
                              text_anchor = "start",
                              transform="rotate(-90,%i,%i)" %( x, y ) )

            self.addElement( e )
Пример #29
0
    def writeFooter(self):
        """write footer."""

        current_x = self.mFooterX
        current_y = self.mFooterY

        if self.mFooter:

            current_y += max(self.mFooterFontSize,
                             self.mMaxBoxSize) + self.mSeparator

            e = SVGdraw.text(self.mPageWidth / 2,
                             current_y + self.mFooterFontSize,
                             self.mFooter,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
Пример #30
0
    def writeFooter(self):
        """write footer."""

        current_x = self.mFooterX
        current_y = self.mFooterY

        if self.mFooter:

            current_y += max(self.mFooterFontSize,
                             self.mMaxBoxSize) + self.mSeparator

            e = SVGdraw.text(self.mPageWidth / 2,
                             current_y + self.mFooterFontSize,
                             self.mFooter,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
Пример #31
0
    def writeRowLabels(self):
        """write column headers."""

        x = self.mHeaderWidth

        for contig in self.mSortedContigs2:

            if contig not in self.mMapContig2Start2: continue

            y = self.mHeaderHeight + self.mMapContig2Start2[
                contig] + self.mMapContig2Size2[contig]
            e = SVGdraw.text(x,
                             y,
                             contig,
                             self.mLabelFontSize * self.mFontSizeFactor,
                             self.mLabelFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start",
                             transform="rotate(-90,%i,%i)" % (x, y))

            self.addElement(e)
Пример #32
0
    def getElements(self, node_id, x1, x2, y):

        e = BranchDecoratorHorizontal.getElements(self, node_id, x1, x2, y)

        text = self.getText(node_id)

        d = x2 - x1
        df = len(text) * (self.mFontSize / 2)
        if df > d:
            x = x1 - df
        else:
            x = x1 + (x2 - x1 - df) / 2

        e.append(SVGdraw.text(x, y - 5,
                              text,
                              self.mFontSize,
                              self.mFont,
                              stroke="rgb(%i,%i,%i)" % self.mFontColour,
                              text_anchor="left"))

        return e
Пример #33
0
    def writeRowHeaders( self ):
        """write row headers."""

        current_x = self.mDataWidth + self.mSeparator
        
        current_y = self.mHeaderHeight + self.mSeparator + self.mHeaderFontSize

        for name in self.mRowNames:
            e = SVGdraw.text( current_x,
                              current_y,
                              name,
                              self.mHeaderFontSize,
                              self.mHeaderFont,
                              stroke = "rgb(%i,%i,%i)" % BLACK,
                              text_anchor = "start")
            
            self.addElement(e)
            
            current_y += self.mRowHeight

        self.mHeaderWidth = max( map( len, self.mRowNames) ) * self.mHeaderFontSize / 2
Пример #34
0
    def writeRowHeaders(self):
        """write row headers."""

        current_x = self.mDataWidth + self.mSeparator

        current_y = self.mHeaderHeight + self.mSeparator + self.mHeaderFontSize

        for name in self.mRowNames:
            e = SVGdraw.text(current_x,
                             current_y,
                             name,
                             self.mHeaderFontSize,
                             self.mHeaderFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start")

            self.addElement(e)

            current_y += self.mRowHeight

        self.mHeaderWidth = max(map(len,
                                    self.mRowNames)) * self.mHeaderFontSize / 2
Пример #35
0
    def getElements(self, node_id, x1, x2, y):

        e = BranchDecoratorHorizontal.getElements(self, node_id, x1, x2, y)

        text = self.getText(node_id)

        d = x2 - x1
        df = len(text) * (self.mFontSize / 2)
        if df > d:
            x = x1 - df
        else:
            x = x1 + (x2 - x1 - df) / 2

        e.append(
            SVGdraw.text(x,
                         y - 5,
                         text,
                         self.mFontSize,
                         self.mFont,
                         stroke="rgb(%i,%i,%i)" % self.mFontColour,
                         text_anchor="left"))

        return e
Пример #36
0
    def getElements(self, node_id, x1, x2, y):

        e = SVGTree.BranchDecoratorHorizontal.getElements(
            self, node_id, x1, x2, y)

        table_id = str(int(self.mTree.node(node_id).data.branchlength))

        if table_id not in self.mTables:
            return e

        startx = x1 + self.mFontSize
        y = y + self.mFontSize

        table, column_widths = self.mTables[table_id], self.mColumnWidths[
            table_id]

        font_weight = "bold"

        for r, row in enumerate(table):
            x = startx

            for c, col in enumerate(row):
                e.append(
                    SVGdraw.text(x,
                                 y,
                                 col,
                                 20,
                                 self.mFont,
                                 stroke="rgb(%i,%i,%i)" % self.mFontColour,
                                 font_weight=font_weight,
                                 text_anchor="left"))
                x += column_widths[c] * self.mFontSize // 2

            y += self.mFontSize
            font_weight = "normal"

        return e
Пример #37
0
    def writeGrid(self):
        """add grid lines."""

        # print last circle
        self.mRadius = self.mRadiusMax + self.mRadiusIncrement
        self.addSeparator()

        # print separators
        for contig, pos in self.contig2Position.items():

            pos = self.getPosition(contig, "+", 0)

            angle = self.getAngle(pos)

            x, y = self.getPosOnArc(angle, self.mRadius)

            e = SVGdraw.line(self.mDataMiddleX,
                             self.mDataMiddleY,
                             x,
                             y,
                             stroke="rgb(%i,%i,%i)" % BLACK)

            self.addElement(e, self.mPlaneGrid)

            x, y = self.getPosOnArc(
                angle, (self.mRadius + self.mRadiusStart) / 2)

            e = SVGdraw.text(x,
                             y,
                             contig,
                             self.mHeaderFontSize,
                             self.mHeaderFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start",
                             transform="rotate(%i,%i,%i)" % (angle, x, y))

            self.addElement(e)
Пример #38
0
    def writeGrid(self):
        """add grid lines."""

        # print last circle
        self.mRadius = self.mRadiusMax + self.mRadiusIncrement
        self.addSeparator()

        # print separators
        for contig, pos in self.contig2Position.items():

            pos = self.getPosition(contig, "+", 0)

            angle = self.getAngle(pos)

            x, y = self.getPosOnArc(angle, self.mRadius)

            e = SVGdraw.line(self.mDataMiddleX,
                             self.mDataMiddleY,
                             x,
                             y,
                             stroke="rgb(%i,%i,%i)" % BLACK)

            self.addElement(e, self.mPlaneGrid)

            x, y = self.getPosOnArc(angle,
                                    (self.mRadius + self.mRadiusStart) / 2)

            e = SVGdraw.text(x,
                             y,
                             contig,
                             self.mHeaderFontSize,
                             self.mHeaderFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start",
                             transform="rotate(%i,%i,%i)" % (angle, x, y))

            self.addElement(e)
Пример #39
0
    def getElements(self, x, y, map_node2height):

        t = self.mTree.get_terminals()

        elements = []

        # print locations
        if self.mPrintLocation:
            for i in range(len(t)):
                node_id1 = t[i]
                taxon1 = self.mTree.node(node_id1).data.taxon
                y1 = map_node2height[node_id1] + y

                elements.append(SVGdraw.text(x, y1,
                                             str(self.mMapId2Location[
                                                 taxon1]),
                                             self.mFontSize,
                                             self.mFont,
                                             stroke="rgb(%i,%i,%i)" % BLACK,
                                             text_anchor="left"))

        # print connectors
        for i in range(len(t) - 1):
            node_id1 = t[i]
            taxon1 = self.mTree.node(node_id1).data.taxon
            y1 = map_node2height[node_id1] + y

            for j in range(i + 1, len(t)):
                node_id2 = t[j]

                taxon2 = self.mTree.node(node_id2).data.taxon

                if self.mExtractSpecies:
                    species1 = self.mExtractSpecies(taxon1)
                    species2 = self.mExtractSpecies(taxon2)

                    if species1 != species2:
                        continue

                    if species1 not in self.mMapSpecies2Colour:
                        self.mMapSpecies2Colour[species1] = COLOURS[
                            len(self.mMapSpecies2Colour) % len(COLOURS)]

                    colour = self.mMapSpecies2Colour[species1]

                else:
                    colour = self.mDefaultColour

                l1 = self.mMapId2Location[taxon1]
                l2 = self.mMapId2Location[taxon2]
                if l1.contig != l2.contig:
                    continue

                if self.mMaxSeparation:
                    s = min(abs(l1.mFrom - l2.mTo), abs(l1.mTo - l2.mFrom))
                    if s >= self.mMaxSeparation:
                        continue

                y2 = map_node2height[node_id2] + y

                distance = y2 - y1

                d = SVGdraw.pathdata(x, y1)

                d.line(x + self.mTickWidth, y1)
                d.ellarc(distance, distance, 0, 0, 1, x + self.mTickWidth, y2)
                d.line(x, y2)

                e = SVGdraw.path(d,
                                 fill="none",
                                 stroke="rgb(%i,%i,%i)" % colour,
                                 stroke_width=1)

                elements.append(e)

        return elements
Пример #40
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """
        total_branch_length = (
            max(self.mNodeWidthsEnd) - min(self.mNodeWidthsStart)) / self.mBranchScaleFactor

        self.mFooterX = self.getHeaderWidth()
        self.mFooterY = self.getHeaderHeight(
        ) + self.mDataHeight + self.mSeparatorHeight

        ruler_start = self.mFooterX
        ruler_end = self.mFooterX + \
            int(total_branch_length * self.mBranchScaleFactor)

        if "ruler" in self.mRulerElements:
            # full length ruler with tick marks and labels
            e = SVGdraw.line(ruler_start,
                             self.mFooterY + self.mRulerTickSize + 1,
                             ruler_end,
                             self.mFooterY + self.mRulerTickSize + 1,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=1)
            self.addElement(e)

            # get reasonable intervalls

        increment = self.mRulerIncrement * self.mBranchScaleFactor

        # adjust increment for extremely long trees
        if (ruler_end - ruler_start) / increment > 1000:
            increment = (ruler_end - ruler_start) / 1000.0
            self.mRulerIncrement = increment / self.mBranchScaleFactor

        if "right-ticks" in self.mRulerElements:

            x = ruler_end
            while x >= ruler_start:
                e = SVGdraw.line(x,
                                 self.mFooterY,
                                 x,
                                 self.mFooterY + 2 * self.mRulerTickSize + 1,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 stroke_width=1)
                self.addElement(e)
                x -= self.mRulerIncrement * self.mBranchScaleFactor

            self.mFooterY += 2 * self.mRulerTickSize + \
                1 + self.mSeparatorHeight

        if "left-ticks" in self.mRulerElements:

            x = ruler_start
            while x <= ruler_end:
                e = SVGdraw.line(x,
                                 self.mFooterY,
                                 x,
                                 self.mFooterY + 2 * self.mRulerTickSize + 1,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 stroke_width=1)
                self.addElement(e)
                x += increment

            self.mFooterY += 2 * self.mRulerTickSize + \
                1 + self.mSeparatorHeight

        if "scale" in self.mRulerElements:

            w = int(self.mRulerIncrement * self.mBranchScaleFactor)

            e = SVGdraw.line(ruler_end,
                             self.mFooterY + self.mRulerTickSize + 1,
                             ruler_end - w,
                             self.mFooterY + self.mRulerTickSize + 1,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=1)

            self.addElement(e)

            e = SVGdraw.line(ruler_end,
                             self.mFooterY,
                             ruler_end,
                             self.mFooterY + 2 * self.mRulerTickSize + 1,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=1)

            self.addElement(e)

            e = SVGdraw.line(ruler_end - w,
                             self.mFooterY,
                             ruler_end - w,
                             self.mFooterY + 2 * self.mRulerTickSize + 1,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=1)

            self.addElement(e)

            e = SVGdraw.text(ruler_end - w / 2,
                             self.mFooterY + 2 * self.mRulerTickSize +
                             1 + self.mRulerFontSize,
                             self.mRulerFormat % self.mRulerIncrement,
                             self.mRulerFontSize,
                             self.mRulerFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
            self.mFooterY += 2 * self.mRulerTickSize + 1 + self.mRulerFontSize

        e, self.mFooterX, self.mFooterY = self.mDecoratorExternalNodes.getLegend(
            self.mFooterX, self.mFooterY)
        self.addElements(e)
        e, self.mFooterX, self.mFooterY = self.mDecoratorInternalNodes.getLegend(
            self.mFooterX, self.mFooterY)
        self.addElements(e)
Пример #41
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """
        current_x = self.mFooterFrom
        current_y = self.mHeaderHeight + self.mDataHeight + 2 * self.mSeparator

        ###########################################################
        # Draw legend 1: size of boxes
        e = SVGdraw.text(current_x,
                         current_y + self.mFooterFontSize,
                         self.mThresholdsSizeTitle,
                         self.mFooterFontSize,
                         self.mFooterFont,
                         stroke="rgb(%i,%i,%i)" % BLACK,
                         text_anchor="start")

        current_x += len(self.mThresholdsSizeTitle) * \
            self.mFooterFontSize / 1.5 + self.mSeparator

        self.mElements.append(e)

        l = len(self.mThresholdsSize)
        for x in range(l):
            if self.mRevertSize:
                p = int(self.mMaxBoxSize * (1.0 - float(x) / l))
            else:
                p = int(self.mMaxBoxSize * (float(x) / l))

            e = SVGdraw.rect(current_x,
                             current_y + (self.mMaxBoxSize - p) / 2,
                             p, p,
                             stroke="black",
                             fill="rgb(%i,%i,%i)" % self.startColour)

            self.mElements.append(e)
            current_x += self.mMaxBoxSize + self.mSeparator

            t = "< %g" % (self.mThresholdsSize[x])
            e = SVGdraw.text(current_x,
                             current_y + self.mFooterFontSize,
                             t,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start")

            current_x += len(t) * self.mFooterFontSize / 1.5 + self.mSeparator
            self.mElements.append(e)

        ###########################################################
        # Draw legend 2: colour of boxes
        current_x = self.mFooterFrom
        current_y += max(self.mFooterFontSize, self.mMaxBoxSize) + \
            self.mSeparator

        e = SVGdraw.text(current_x,
                         current_y + self.mFooterFontSize,
                         self.mThresholdsColourTitle,
                         self.mFooterFontSize,
                         self.mFooterFont,
                         stroke="rgb(%i,%i,%i)" % BLACK,
                         text_anchor="start")

        current_x += len(self.mThresholdsColourTitle) * \
            self.mFooterFontSize / 1.5 + self.mSeparator

        self.mElements.append(e)

        l = len(self.mThresholdsColour)

        for x in range(l + 1):

            p = self.mMaxBoxSize

            if x < l:
                t = "< %g" % (self.mThresholdsColour[x])
            else:
                t = "> %g" % (self.mThresholdsColour[x - 1])

            e = SVGdraw.rect(current_x,
                             current_y,
                             p, p,
                             stroke="black",
                             fill="rgb(%i,%i,%i)" % self.mColours[x])

            self.mElements.append(e)
            current_x += self.mMaxBoxSize + self.mSeparator

            e = SVGdraw.text(current_x,
                             current_y + self.mFooterFontSize,
                             t,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start")

            current_x += len(t) * self.mFooterFontSize / 1.5 + self.mSeparator
            self.mElements.append(e)

        ###########################################################
        if self.mMaxPValue is not None or self.mMaxQValue is not None:
            current_y += max(self.mFooterFontSize / 1.5,
                             self.mMaxBoxSize) + self.mSeparator

            a = []
            if self.mMaxPValue:
                a.append("P < %6.4f" % self.mMaxPValue)
            if self.mMaxQValue:
                a.append("FDR = %6.4f" % self.mMaxQValue)

            e = SVGdraw.text(self.mPageWidth / 2,
                             current_y + self.mFooterFontSize,
                             " ".join(a),
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

        ###########################################################
        if self.mFooter:

            current_y += max(self.mFooterFontSize / 1.5,
                             self.mMaxBoxSize) + self.mSeparator

            e = SVGdraw.text(self.mPageWidth / 2,
                             current_y + self.mFooterFontSize,
                             self.mFooter,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.mElements.append(e)
Пример #42
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """
        current_x = self.mFooterFrom
        current_y = self.mHeaderHeight + self.mDataHeight + 2 * self.mSeparator

        ###########################################################
        # Draw legend 1: size of boxes
        e = SVGdraw.text(current_x,
                         current_y + self.mFooterFontSize,
                         self.mThresholdsSizeTitle,
                         self.mFooterFontSize,
                         self.mFooterFont,
                         stroke="rgb(%i,%i,%i)" % BLACK,
                         text_anchor="start")

        current_x += len(self.mThresholdsSizeTitle) * \
            self.mFooterFontSize / 1.5 + self.mSeparator

        self.mElements.append(e)

        l = len(self.mThresholdsSize)
        for x in range(l):
            if self.mRevertSize:
                p = int(self.mMaxBoxSize * (1.0 - float(x) / l))
            else:
                p = int(self.mMaxBoxSize * (float(x) / l))

            e = SVGdraw.rect(current_x,
                             current_y + (self.mMaxBoxSize - p) / 2,
                             p,
                             p,
                             stroke="black",
                             fill="rgb(%i,%i,%i)" % self.startColour)

            self.mElements.append(e)
            current_x += self.mMaxBoxSize + self.mSeparator

            t = "< %g" % (self.mThresholdsSize[x])
            e = SVGdraw.text(current_x,
                             current_y + self.mFooterFontSize,
                             t,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start")

            current_x += len(t) * self.mFooterFontSize / 1.5 + self.mSeparator
            self.mElements.append(e)

        ###########################################################
        # Draw legend 2: colour of boxes
        current_x = self.mFooterFrom
        current_y += max(self.mFooterFontSize, self.mMaxBoxSize) + \
            self.mSeparator

        e = SVGdraw.text(current_x,
                         current_y + self.mFooterFontSize,
                         self.mThresholdsColourTitle,
                         self.mFooterFontSize,
                         self.mFooterFont,
                         stroke="rgb(%i,%i,%i)" % BLACK,
                         text_anchor="start")

        current_x += len(self.mThresholdsColourTitle) * \
            self.mFooterFontSize / 1.5 + self.mSeparator

        self.mElements.append(e)

        l = len(self.mThresholdsColour)

        for x in range(l + 1):

            p = self.mMaxBoxSize

            if x < l:
                t = "< %g" % (self.mThresholdsColour[x])
            else:
                t = "> %g" % (self.mThresholdsColour[x - 1])

            e = SVGdraw.rect(current_x,
                             current_y,
                             p,
                             p,
                             stroke="black",
                             fill="rgb(%i,%i,%i)" % self.mColours[x])

            self.mElements.append(e)
            current_x += self.mMaxBoxSize + self.mSeparator

            e = SVGdraw.text(current_x,
                             current_y + self.mFooterFontSize,
                             t,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="start")

            current_x += len(t) * self.mFooterFontSize / 1.5 + self.mSeparator
            self.mElements.append(e)

        ###########################################################
        if self.mMaxPValue is not None or self.mMaxQValue is not None:
            current_y += max(self.mFooterFontSize / 1.5,
                             self.mMaxBoxSize) + self.mSeparator

            a = []
            if self.mMaxPValue:
                a.append("P < %6.4f" % self.mMaxPValue)
            if self.mMaxQValue:
                a.append("FDR = %6.4f" % self.mMaxQValue)

            e = SVGdraw.text(self.mPageWidth / 2,
                             current_y + self.mFooterFontSize,
                             " ".join(a),
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

        ###########################################################
        if self.mFooter:

            current_y += max(self.mFooterFontSize / 1.5,
                             self.mMaxBoxSize) + self.mSeparator

            e = SVGdraw.text(self.mPageWidth / 2,
                             current_y + self.mFooterFontSize,
                             self.mFooter,
                             self.mFooterFontSize,
                             self.mFooterFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.mElements.append(e)
Пример #43
0
    def getElements(self, x, y, map_node2height):

        t = self.mTree.get_terminals()

        elements = []

        # print locations
        if self.mPrintLocation:
            for i in range(len(t)):
                node_id1 = t[i]
                taxon1 = self.mTree.node(node_id1).data.taxon
                y1 = map_node2height[node_id1] + y

                elements.append(
                    SVGdraw.text(x,
                                 y1,
                                 str(self.mMapId2Location[taxon1]),
                                 self.mFontSize,
                                 self.mFont,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 text_anchor="left"))

        # print connectors
        for i in range(len(t) - 1):
            node_id1 = t[i]
            taxon1 = self.mTree.node(node_id1).data.taxon
            y1 = map_node2height[node_id1] + y

            for j in range(i + 1, len(t)):
                node_id2 = t[j]

                taxon2 = self.mTree.node(node_id2).data.taxon

                if self.mExtractSpecies:
                    species1 = self.mExtractSpecies(taxon1)
                    species2 = self.mExtractSpecies(taxon2)

                    if species1 != species2:
                        continue

                    if species1 not in self.mMapSpecies2Colour:
                        self.mMapSpecies2Colour[species1] = COLOURS[len(
                            self.mMapSpecies2Colour) % len(COLOURS)]

                    colour = self.mMapSpecies2Colour[species1]

                else:
                    colour = self.mDefaultColour

                l1 = self.mMapId2Location[taxon1]
                l2 = self.mMapId2Location[taxon2]
                if l1.contig != l2.contig:
                    continue

                if self.mMaxSeparation:
                    s = min(abs(l1.mFrom - l2.mTo), abs(l1.mTo - l2.mFrom))
                    if s >= self.mMaxSeparation:
                        continue

                y2 = map_node2height[node_id2] + y

                distance = y2 - y1

                d = SVGdraw.pathdata(x, y1)

                d.line(x + self.mTickWidth, y1)
                d.ellarc(distance, distance, 0, 0, 1, x + self.mTickWidth, y2)
                d.line(x, y2)

                e = SVGdraw.path(d,
                                 fill="none",
                                 stroke="rgb(%i,%i,%i)" % colour,
                                 stroke_width=1)

                elements.append(e)

        return elements
Пример #44
0
    def writeFooter(self):
        """write footer.

        The footer contains the legend.
        """
        total_branch_length = (max(self.mNodeWidthsEnd) - min(
            self.mNodeWidthsStart)) / self.mBranchScaleFactor

        self.mFooterX = self.getHeaderWidth()
        self.mFooterY = self.getHeaderHeight(
        ) + self.mDataHeight + self.mSeparatorHeight

        ruler_start = self.mFooterX
        ruler_end = self.mFooterX + \
            int(total_branch_length * self.mBranchScaleFactor)

        if "ruler" in self.mRulerElements:
            # full length ruler with tick marks and labels
            e = SVGdraw.line(ruler_start,
                             self.mFooterY + self.mRulerTickSize + 1,
                             ruler_end,
                             self.mFooterY + self.mRulerTickSize + 1,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=1)
            self.addElement(e)

            # get reasonable intervalls

        increment = self.mRulerIncrement * self.mBranchScaleFactor

        # adjust increment for extremely long trees
        if (ruler_end - ruler_start) / increment > 1000:
            increment = (ruler_end - ruler_start) / 1000.0
            self.mRulerIncrement = increment / self.mBranchScaleFactor

        if "right-ticks" in self.mRulerElements:

            x = ruler_end
            while x >= ruler_start:
                e = SVGdraw.line(x,
                                 self.mFooterY,
                                 x,
                                 self.mFooterY + 2 * self.mRulerTickSize + 1,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 stroke_width=1)
                self.addElement(e)
                x -= self.mRulerIncrement * self.mBranchScaleFactor

            self.mFooterY += 2 * self.mRulerTickSize + \
                1 + self.mSeparatorHeight

        if "left-ticks" in self.mRulerElements:

            x = ruler_start
            while x <= ruler_end:
                e = SVGdraw.line(x,
                                 self.mFooterY,
                                 x,
                                 self.mFooterY + 2 * self.mRulerTickSize + 1,
                                 stroke="rgb(%i,%i,%i)" % BLACK,
                                 stroke_width=1)
                self.addElement(e)
                x += increment

            self.mFooterY += 2 * self.mRulerTickSize + \
                1 + self.mSeparatorHeight

        if "scale" in self.mRulerElements:

            w = int(self.mRulerIncrement * self.mBranchScaleFactor)

            e = SVGdraw.line(ruler_end,
                             self.mFooterY + self.mRulerTickSize + 1,
                             ruler_end - w,
                             self.mFooterY + self.mRulerTickSize + 1,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=1)

            self.addElement(e)

            e = SVGdraw.line(ruler_end,
                             self.mFooterY,
                             ruler_end,
                             self.mFooterY + 2 * self.mRulerTickSize + 1,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=1)

            self.addElement(e)

            e = SVGdraw.line(ruler_end - w,
                             self.mFooterY,
                             ruler_end - w,
                             self.mFooterY + 2 * self.mRulerTickSize + 1,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             stroke_width=1)

            self.addElement(e)

            e = SVGdraw.text(ruler_end - w / 2,
                             self.mFooterY + 2 * self.mRulerTickSize + 1 +
                             self.mRulerFontSize,
                             self.mRulerFormat % self.mRulerIncrement,
                             self.mRulerFontSize,
                             self.mRulerFont,
                             stroke="rgb(%i,%i,%i)" % BLACK,
                             text_anchor="middle")

            self.addElement(e)
            self.mFooterY += 2 * self.mRulerTickSize + 1 + self.mRulerFontSize

        e, self.mFooterX, self.mFooterY = self.mDecoratorExternalNodes.getLegend(
            self.mFooterX, self.mFooterY)
        self.addElements(e)
        e, self.mFooterX, self.mFooterY = self.mDecoratorInternalNodes.getLegend(
            self.mFooterX, self.mFooterY)
        self.addElements(e)