def getElements(self, node_id, x, y): node = self.mTree.node(node_id) e = [] p = node.data.support if p == 1.0: e.append( SVGdraw.circle(x, y, self.mRadius, stroke="rgb(%i,%i,%i)" % SVGTree.BLACK, fill="rgb(%i,%i,%i)" % SVGTree.RED)) elif p > 0.0: e.append( SVGdraw.circle(x, y, self.mRadius, stroke="rgb(%i,%i,%i)" % SVGTree.BLACK, fill="rgb(%i,%i,%i)" % SVGTree.WHITE)) d = SVGdraw.pathdata(x, y) d.line(x + self.mRadius, y) angle = 360.0 * p dx = self.mRadius * math.cos(math.radians(angle)) + x dy = self.mRadius * math.sin(math.radians(angle)) + y if p <= 0.5: d.ellarc(self.mRadius, self.mRadius, 0, 0, 1, dx, dy) else: d.ellarc(self.mRadius, self.mRadius, 0, 1, 1, dx, dy) e.append( SVGdraw.path(d, stroke="rgb(%i,%i,%i)" % SVGTree.RED, fill="rgb(%i,%i,%i)" % SVGTree.RED, stroke_width=self.mStrokeWidth)) else: pass return e
def getElements(self, node_id, x, y): node = self.mTree.node(node_id) e = [] p = node.data.support if p == 1.0: e.append(SVGdraw.circle(x, y, self.mRadius, stroke="rgb(%i,%i,%i)" % SVGTree.BLACK, fill="rgb(%i,%i,%i)" % SVGTree.RED)) elif p > 0.0: e.append(SVGdraw.circle(x, y, self.mRadius, stroke="rgb(%i,%i,%i)" % SVGTree.BLACK, fill="rgb(%i,%i,%i)" % SVGTree.WHITE)) d = SVGdraw.pathdata(x, y) d.line(x + self.mRadius, y) angle = 360.0 * p dx = self.mRadius * math.cos(math.radians(angle)) + x dy = self.mRadius * math.sin(math.radians(angle)) + y if p <= 0.5: d.ellarc(self.mRadius, self.mRadius, 0, 0, 1, dx, dy) else: d.ellarc(self.mRadius, self.mRadius, 0, 1, 1, dx, dy) e.append(SVGdraw.path(d, stroke="rgb(%i,%i,%i)" % SVGTree.RED, fill="rgb(%i,%i,%i)" % SVGTree.RED, stroke_width=self.mStrokeWidth)) else: pass return e
def addDuplication(self, entries, map_gene2pos, height, url=None, with_separator=True, link_to_previous=False, quality2symbol={}, quality2mask={}): """add a dot in row/col.""" mi, ma = None, 0 pos = bisect.bisect(self.mColourThresholds, height) master_colour = self.mColours[pos] chrs = {} points = [] if not link_to_previous: self.mPreviousPoints = {} ######################################################## ######################################################## ######################################################## # convert gene list to a set of points ######################################################## for species, transcript, gene, quality in entries: chr, strand, first_res, last_res = map_gene2pos[gene] chrs[chr] = 1 pos1 = self.getPosition(chr, strand, first_res) pos2 = self.getPosition(chr, strand, last_res) a = min(pos1, pos2) b = max(pos1, pos2) if mi is None: mi = a else: mi = min(a, mi) ma = max(b, ma) points.append((pos1, pos2, gene, quality, chr)) ######################################################## ######################################################## ######################################################## # decide whether we need to increment the radius ######################################################## cis = len(chrs) == 1 old_radius = self.mRadius is_overlap = False if cis: if not self.mLastChr: self.mLastChr = chr if chr != self.mLastChr: self.mRadius = self.mRadiusFallBack self.mLastMax = ma self.mPreviousMax = ma self.mLastChr = chr else: if self.mPreviousMax + self.mMinDistance > mi: # overlap due to close proximitiy self.mRadius += self.mRadiusIncrement if with_separator: self.addSeparator() # true overlap if self.mPreviousMax > mi: is_overlap = True elif self.mLastMax + self.mMinDistance > mi: pass else: self.mRadius = self.mRadiusFallBack self.mLastMax = max(self.mLastMax, ma) else: if self.mLastMax > mi: self.mRadius += self.mRadiusIncrement if with_separator: self.addSeparator() self.mPreviousMin = mi self.mPreviousMax = ma self.mPreviousCis = cis self.mRadiusMax = max(self.mRadius, self.mRadiusMax) ######################################################## ######################################################## ######################################################## # draw points ######################################################## link_colour = master_colour link_rad_width = self.mLinkRadStrokeWidth link_arc_width = self.mLinkArcStrokeWidth new_points = {} for pos1, pos2, gene, quality, chr in points: angle = self.getAngle((pos1 + pos2) / 2) x, y = self.getPosOnArc(angle, self.mRadius) try: symbol = quality2symbol[quality] except KeyError: symbol = "rect" if quality in quality2mask: colour = self.mLinkColourSymbolMasked link_colour = self.mLinkColourMasked link_rad_width = self.mLinkStrokeWidthMasked link_arc_width = self.mLinkStrokeWidthMasked else: colour = master_colour if gene in self.mPreviousPoints: continue new_points[gene] = (x, y, angle, quality, chr) if symbol == "circle": ee = SVGdraw.circle(x, y, self.mLinkSymbolSize, fill="rgb(%i,%i,%i)" % colour, stroke="black", stroke_width=self.mLinkStrokeWidthSymbol) elif symbol == "rect": ee = SVGdraw.rect(x - self.mLinkSymbolSize / 2, y - self.mLinkSymbolSize / 2, self.mLinkSymbolSize, self.mLinkSymbolSize, fill="rgb(%i,%i,%i)" % colour, stroke="black", stroke_width=self.mLinkStrokeWidthSymbol) if url: e = SVGdraw.link(url % gene) e.addElement(ee) else: e = ee self.addWheelElement(e) ######################################################## ######################################################## ######################################################## # write all arcs in between old points and new points # cis: circular arc # trans: radial arc ######################################################## angles = [] for x1, y1, angle1, quality1, chr1 in new_points.values(): # reduce clutter by not writing arc to the same angle for x2, y2, angle2, quality2, chr2 in self.mPreviousPoints.values(): for a in angles: if a - self.mAngleResolution < angle2 < a + self.mAngleResolution: break else: angles.append(angle2) d = SVGdraw.pathdata(x1, y1) if chr1 == chr2: d.relellarc( self.mRadius, self.mRadius, 0, 0, 1, x2 - x1, y2 - y1) link_width = link_rad_width else: d.relellarc( self.mRadius * 2, self.mRadius * 2, 0, 0, 0, x2 - x1, y2 - y1) link_width = link_arc_width e = SVGdraw.path(d, fill="none", stroke="rgb(%i,%i,%i)" % link_colour, stroke_width=link_width) self.addWheelElement(e, self.mPlaneLinks) # plot lines between new points new_genes = new_points.keys() for g1 in range(len(new_genes) - 1): x1, y1, angle1, quality1, chr1 = new_points[new_genes[g1]] for g2 in range(g1 + 1, len(new_genes)): x2, y2, angle2, quality2, chr2 = new_points[new_genes[g2]] for a in angles: if a - self.mAngleResolution < angle2 < a + self.mAngleResolution: break else: angles.append(angle2) d = SVGdraw.pathdata(x1, y1) if chr1 == chr2: d.relellarc( self.mRadius, self.mRadius, 0, 0, 1, x2 - x1, y2 - y1) link_width = link_rad_width else: d.relellarc( self.mRadius * 2, self.mRadius * 2, 0, 0, 0, x2 - x1, y2 - y1) link_width = link_arc_width e = SVGdraw.path(d, fill="none", stroke="rgb(%i,%i,%i)" % link_colour, stroke_width=link_width) self.addWheelElement(e, self.mPlaneLinks) # add new points to old points for k, v in new_points.items(): self.mPreviousPoints[k] = v
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
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
def addDuplication(self, entries, map_gene2pos, height, url=None, with_separator=True, link_to_previous=False, quality2symbol={}, quality2mask={}): """add a dot in row/col.""" mi, ma = None, 0 pos = bisect.bisect(self.mColourThresholds, height) master_colour = self.mColours[pos] chrs = {} points = [] for species, transcript, gene, quality in entries: chr, strand, first_res, last_res = map_gene2pos[gene] chrs[chr] = 1 pos1 = self.getPosition(chr, strand, first_res) pos2 = self.getPosition(chr, strand, last_res) a = min(pos1, pos2) b = max(pos1, pos2) if mi is None: mi = a else: mi = min(a, mi) ma = max(b, ma) points.append((pos1, pos2, gene, quality)) # decide whether we need to increment the radius cis = len(chrs) == 1 old_radius = self.mRadius is_overlap = False if cis: if not self.mLastChr: self.mLastChr = chr if chr != self.mLastChr: self.mRadius = self.mRadiusFallBack self.mLastMax = ma self.mPreviousMax = ma self.mLastChr = chr else: if self.mPreviousMax + self.mMinDistance > mi: # overlap due to close proximitiy self.mRadius += self.mRadiusIncrement if with_separator: self.addSeparator() # true overlap if self.mPreviousMax > mi: is_overlap = True elif self.mLastMax + self.mMinDistance > mi: pass else: self.mRadius = self.mRadiusFallBack self.mLastMax = max(self.mLastMax, ma) else: if self.mLastMax > mi: self.mRadius += self.mRadiusIncrement if with_separator: self.addSeparator() if cis and self.mPreviousCis and (link_to_previous or is_overlap): # print old_x1, old_y1, old_x2, old_y2, new_x1, new_y2, new_x2, # new_y2 r1 = old_radius r2 = self.mRadius old_x1, old_y1 = self.getPosOnArcForRadius(self.mPreviousMin, r1) old_x2, old_y2 = self.getPosOnArcForRadius(self.mPreviousMax, r1) new_x1, new_y1 = self.getPosOnArcForRadius(mi, r2) new_x2, new_y2 = self.getPosOnArcForRadius(ma, r2) if link_to_previous: # print cis, entries, chrs d = SVGdraw.pathdata(old_x1, old_y1) d.ellarc(r1, r1, 0, 0, 1, old_x2, old_y2) d.line(new_x2, new_y2) d.ellarc(r2, r2, 0, 0, 1, new_x1, new_y1) d.line(old_x1, old_y1) e = SVGdraw.path(d, fill="rgb(%i,%i,%i)" % GREY, stroke="rgb(%i,%i,%i)" % GREY, stroke_width=1) else: # get points of center old_x1, old_y1 = self.getPosOnArcForRadius( (self.mPreviousMax + self.mPreviousMin) / 2, r1) new_x1, new_y1 = self.getPosOnArcForRadius((ma + mi) / 2, r2) # lines for interleaved spans: skip if not ((self.mPreviousMin < mi and self.mPreviousMax > ma) or (self.mPreviousMin > mi and self.mPreviousMax < ma)): ## d = SVGdraw.pathdata( old_x2, old_y2 ) ## d.line( new_x2, new_y2 ) ## d.move( new_x1, new_y1 ) ## d.line( old_x1, old_y1 ) ## d.move( old_x2, old_y2 ) # e = SVGdraw.path( d, ## fill = "none", ## stroke = "rgb(%i,%i,%i)" % BLACK, # stroke_width = self.mMarkerWidth / 2 ) e = SVGdraw.line(old_x1, old_y1, new_x1, new_y1, fill="none", stroke="rgb(%i,%i,%i)" % GREY, stroke_width=self.mMarkerWidth / 2) else: # lines for covering spans, as these overlaps e = None # e = SVGdraw.line( old_x1, old_y1, ## new_x1, new_y1, ## fill = "none", ## stroke = "rgb(%i,%i,%i)" % GREY, # stroke_width = self.mMarkerWidth / 2 ) if e: self.addElement(e, self.mPlaneJoins) self.mPreviousMin = mi self.mPreviousMax = ma self.mPreviousCis = cis self.mRadiusMax = max(self.mRadius, self.mRadiusMax) # draw points link_colour = master_colour link_width = 10 for pos1, pos2, gene, quality in points: angle = self.getAngle((pos1 + pos2) / 2) x, y = self.getPosOnArc(angle, self.mRadius) try: symbol = quality2symbol[quality] except KeyError: symbol = "rect" if quality in quality2mask: colour = GREY link_colour = GREY link_width = 1 else: colour = master_colour if symbol == "circle": ee = SVGdraw.circle(x, y, self.mMarkerWidth, fill="rgb(%i,%i,%i)" % colour, stroke="black", stroke_width=1) elif symbol == "rect": ee = SVGdraw.rect(x - self.mMarkerWidth / 2, y - self.mMarkerWidth / 2, self.mMarkerWidth, self.mMarkerWidth, fill="rgb(%i,%i,%i)" % colour, stroke="black", stroke_width=1) if url: e = SVGdraw.link(url % gene) e.addElement(ee) else: e = ee self.addElement(e) angle1 = self.getAngle(mi) angle2 = self.getAngle(ma) x1, y1 = self.getPosOnArc(angle1, self.mRadius) x2, y2 = self.getPosOnArc(angle2, self.mRadius) d = SVGdraw.pathdata(x1, y1) if cis: d.ellarc(self.mRadius, self.mRadius, 0, 0, 1, x2, y2) else: d.ellarc(self.mRadius * 2, self.mRadius * 2, 0, 0, 0, x2, y2) e = SVGdraw.path(d, fill="none", stroke="rgb(%i,%i,%i)" % link_colour, stroke_width=link_width) self.addElement(e)
def addDuplication( self, entries, map_gene2pos, height, url = None, with_separator=True, link_to_previous = False, quality2symbol = {}, quality2mask = {}): """add a dot in row/col.""" mi, ma = None, 0 pos = bisect.bisect( self.mColourThresholds, height ) master_colour = self.mColours[pos] chrs = {} points = [] for species, transcript, gene, quality in entries: chr, strand, first_res, last_res = map_gene2pos[gene] chrs[chr] = 1 pos1 = self.getPosition( chr, strand, first_res ) pos2 = self.getPosition( chr, strand, last_res ) a = min( pos1, pos2 ) b = max( pos1, pos2 ) if mi == None: mi = a else: mi = min(a, mi) ma = max(b, ma) points.append( (pos1, pos2, gene, quality) ) ## decide whether we need to increment the radius cis = len(chrs) == 1 old_radius = self.mRadius is_overlap = False if cis: if not self.mLastChr: self.mLastChr = chr if chr != self.mLastChr: self.mRadius = self.mRadiusFallBack self.mLastMax = ma self.mPreviousMax = ma self.mLastChr = chr else: if self.mPreviousMax + self.mMinDistance > mi: ## overlap due to close proximitiy self.mRadius += self.mRadiusIncrement if with_separator: self.addSeparator() ## true overlap if self.mPreviousMax > mi: is_overlap = True elif self.mLastMax + self.mMinDistance > mi: pass else: self.mRadius = self.mRadiusFallBack self.mLastMax = max(self.mLastMax, ma) else: if self.mLastMax > mi: self.mRadius += self.mRadiusIncrement if with_separator: self.addSeparator() if cis and self.mPreviousCis and (link_to_previous or is_overlap): # print old_x1, old_y1, old_x2, old_y2, new_x1, new_y2, new_x2, new_y2 r1 = old_radius r2 = self.mRadius old_x1, old_y1 = self.getPosOnArcForRadius( self.mPreviousMin, r1 ) old_x2, old_y2 = self.getPosOnArcForRadius( self.mPreviousMax, r1 ) new_x1, new_y1 = self.getPosOnArcForRadius( mi, r2 ) new_x2, new_y2 = self.getPosOnArcForRadius( ma, r2 ) if link_to_previous: # print cis, entries, chrs d = SVGdraw.pathdata( old_x1, old_y1 ) d.ellarc( r1, r1, 0, 0, 1, old_x2, old_y2 ) d.line( new_x2, new_y2 ) d.ellarc( r2, r2, 0, 0, 1, new_x1, new_y1 ) d.line( old_x1, old_y1 ) e = SVGdraw.path( d, fill = "rgb(%i,%i,%i)" % GREY, stroke = "rgb(%i,%i,%i)" % GREY, stroke_width = 1 ) else: # get points of center old_x1, old_y1 = self.getPosOnArcForRadius( (self.mPreviousMax + self.mPreviousMin) / 2, r1 ) new_x1, new_y1 = self.getPosOnArcForRadius( (ma + mi) / 2, r2 ) # lines for interleaved spans: skip if not ((self.mPreviousMin < mi and self.mPreviousMax > ma) or \ (self.mPreviousMin > mi and self.mPreviousMax < ma)) : ## d = SVGdraw.pathdata( old_x2, old_y2 ) ## d.line( new_x2, new_y2 ) ## d.move( new_x1, new_y1 ) ## d.line( old_x1, old_y1 ) ## d.move( old_x2, old_y2 ) ## e = SVGdraw.path( d, ## fill = "none", ## stroke = "rgb(%i,%i,%i)" % BLACK, ## stroke_width = self.mMarkerWidth / 2 ) e = SVGdraw.line( old_x1, old_y1, new_x1, new_y1, fill = "none", stroke = "rgb(%i,%i,%i)" % GREY, stroke_width = self.mMarkerWidth / 2 ) else: # lines for covering spans, as these overlaps e = None ## e = SVGdraw.line( old_x1, old_y1, ## new_x1, new_y1, ## fill = "none", ## stroke = "rgb(%i,%i,%i)" % GREY, ## stroke_width = self.mMarkerWidth / 2 ) if e: self.addElement( e, self.mPlaneJoins ) self.mPreviousMin = mi self.mPreviousMax = ma self.mPreviousCis = cis self.mRadiusMax = max(self.mRadius, self.mRadiusMax) ## draw points link_colour = master_colour link_width = 10 for pos1, pos2, gene, quality in points: angle = self.getAngle( (pos1 + pos2) / 2 ) x,y = self.getPosOnArc( angle, self.mRadius ) try: symbol = quality2symbol[quality] except KeyError: symbol = "rect" if quality in quality2mask: colour = GREY link_colour = GREY link_width = 1 else: colour = master_colour if symbol == "circle": ee = SVGdraw.circle( x, y, self.mMarkerWidth, fill = "rgb(%i,%i,%i)" % colour, stroke="black", stroke_width= 1) elif symbol == "rect": ee = SVGdraw.rect( x-self.mMarkerWidth/2, y-self.mMarkerWidth/2, self.mMarkerWidth, self.mMarkerWidth, fill = "rgb(%i,%i,%i)" % colour, stroke="black", stroke_width= 1) if url: e = SVGdraw.link( url % gene ) e.addElement( ee ) else: e = ee self.addElement( e ) angle1 = self.getAngle( mi ) angle2 = self.getAngle( ma ) x1,y1 = self.getPosOnArc( angle1, self.mRadius ) x2,y2 = self.getPosOnArc( angle2, self.mRadius ) d = SVGdraw.pathdata( x1, y1 ) if cis: d.ellarc( self.mRadius, self.mRadius, 0, 0, 1, x2, y2 ) else: d.ellarc( self.mRadius * 2, self.mRadius * 2, 0, 0, 0, x2, y2 ) e = SVGdraw.path( d, fill = "none", stroke = "rgb(%i,%i,%i)" % link_colour, stroke_width = link_width ) self.addElement(e)