Mercurial > repos > cpt > cpt_linear_genome_plot
diff dna_features_viewer/GraphicFeature.py @ 1:e923c686ead9 draft
planemo upload commit 94b0cd1fff0826c6db3e7dc0c91c0c5a8be8bb0c
author | cpt |
---|---|
date | Mon, 05 Jun 2023 02:45:31 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dna_features_viewer/GraphicFeature.py Mon Jun 05 02:45:31 2023 +0000 @@ -0,0 +1,160 @@ +from copy import deepcopy + + +class GraphicFeature: + """Genetic Feature to be plotted. + + Parameters + ---------- + + start, end + Coordinates of the feature in the final sequence. + + strand + Directionality of the feature. can be +1/-1/0 for direct sense, + anti-sense, or no directionality. + + label + Short descriptive text associated and plotted with the feature + + color + Color of the feature, any Matplotlib-compatible format is accepted, + such as "white", "w", "#ffffff", (1,1,1), etc. + + linecolor + Color of the feature's border, any Matplotlib-compatible format is + accepted, such as "white", "w", "#ffffff", (1,1,1), etc. + + linewidth + Width of the line (=edge) surrounding the graphic feature, in pixels. + + thickness + Vertical span of the feature + + box_color + Color of the label box. Set to None for no box around the label. + Leave to "auto" for a box color that is a lightened version of the + feature's color. + + data + Any other keyword is kept into the feature.data[] dictionary. + + fontdict + A Matplotlib fontdict for the font to be used in the label, e.g. + ``size=11``, ``weight='bold'``, ``family='Helvetica'``, etc. + + open_left, open_right + Set to True if this feature does not end on the right or left because it + is a cropped version of a bigger feature. + + box_linewidth + Width of the line delimiting the text box when the annotation is outside + the graphic feature. Set to 0 for no box borders + + box_color + Background color of the annotation's text box. If left to "auto" the + color will be a lighter version of the feature's color. + + label_link_color + Color of the line linking the text annotation to its respective graphic + feature. Set to auto for the line to automatically be a darker version + of the feature's color. + """ + + feature_type = "feature" + + def __init__( + self, + start=None, + end=None, + strand=None, + label=None, + color="#000080", + thickness=14, + linewidth=1.0, + linecolor="#000000", + fontdict=None, + html=None, + open_left=False, + open_right=False, + box_linewidth=1, + box_color="auto", + legend_text=None, + label_link_color="black", + **data + ): + self.start = start + self.end = end + self.strand = strand + self.label = label + self.color = color + self.linecolor = linecolor + self.data = data + self.thickness = thickness + self.linewidth = linewidth + self.box_linewidth = box_linewidth + self.box_color = box_color + self.label_link_color = label_link_color + self.fontdict = dict([("fontsize", 11)] + list((fontdict or {}).items())) + self.html = html + self.open_left = open_left + self.open_right = open_right + self.legend_text = legend_text + + def split_in_two(self, x_coord=0): + """Return two features by cutting this feature at x_coord.""" + copy1 = deepcopy(self) + copy2 = deepcopy(self) + copy1.end = x_coord + copy2.start = x_coord + 1 + return copy1, copy2 + + def crop(self, window): + """Return a the fragment of the feature that is in the window. + + If there is no overlap between the feature location and the window, + None is returned. + """ + s, e = window + if (s > self.end) or (e < self.start): + return None + copy = deepcopy(self) + if s > self.start: + copy.start = s + copy.open_left = True + if e < self.end: + copy.end = e + copy.open_right = True + return copy + + def overlaps_with(self, other): + """Return whether the feature's location overlaps with feature `other`""" + loc1, loc2 = (self.start, self.end), (other.start, other.end) + loc1, loc2 = sorted(loc1), sorted(loc2) + loc1, loc2 = sorted([loc1, loc2], key=lambda loc: loc[0]) + return loc1[1] > loc2[0] + + @property + def length(self): + """Return the length of the feature (end-start)""" + return abs(self.end - self.start) + + @property + def x_center(self): + """Return the x-center of the feature, (start+end)/2""" + return 0.5 * (self.start + self.end - 1) + + @staticmethod + def from_biopython_feature(feature, **props): + """Create a GraphicalFeature from a Biopython.Feature object.""" + return GraphicFeature( + start=feature.location.start, + end=feature.location.end, + strand=feature.location.strand, + **props + ) + + def __repr__(self): + return ("GF(%(label)s, %(start)d-%(end)d " % self.__dict__) + ( + ")" if self.strand is None else "(%d))" % self.strand + )