comparison 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
comparison
equal deleted inserted replaced
0:621754dd31f8 1:e923c686ead9
1 from copy import deepcopy
2
3
4 class GraphicFeature:
5 """Genetic Feature to be plotted.
6
7 Parameters
8 ----------
9
10 start, end
11 Coordinates of the feature in the final sequence.
12
13 strand
14 Directionality of the feature. can be +1/-1/0 for direct sense,
15 anti-sense, or no directionality.
16
17 label
18 Short descriptive text associated and plotted with the feature
19
20 color
21 Color of the feature, any Matplotlib-compatible format is accepted,
22 such as "white", "w", "#ffffff", (1,1,1), etc.
23
24 linecolor
25 Color of the feature's border, any Matplotlib-compatible format is
26 accepted, such as "white", "w", "#ffffff", (1,1,1), etc.
27
28 linewidth
29 Width of the line (=edge) surrounding the graphic feature, in pixels.
30
31 thickness
32 Vertical span of the feature
33
34 box_color
35 Color of the label box. Set to None for no box around the label.
36 Leave to "auto" for a box color that is a lightened version of the
37 feature's color.
38
39 data
40 Any other keyword is kept into the feature.data[] dictionary.
41
42 fontdict
43 A Matplotlib fontdict for the font to be used in the label, e.g.
44 ``size=11``, ``weight='bold'``, ``family='Helvetica'``, etc.
45
46 open_left, open_right
47 Set to True if this feature does not end on the right or left because it
48 is a cropped version of a bigger feature.
49
50 box_linewidth
51 Width of the line delimiting the text box when the annotation is outside
52 the graphic feature. Set to 0 for no box borders
53
54 box_color
55 Background color of the annotation's text box. If left to "auto" the
56 color will be a lighter version of the feature's color.
57
58 label_link_color
59 Color of the line linking the text annotation to its respective graphic
60 feature. Set to auto for the line to automatically be a darker version
61 of the feature's color.
62 """
63
64 feature_type = "feature"
65
66 def __init__(
67 self,
68 start=None,
69 end=None,
70 strand=None,
71 label=None,
72 color="#000080",
73 thickness=14,
74 linewidth=1.0,
75 linecolor="#000000",
76 fontdict=None,
77 html=None,
78 open_left=False,
79 open_right=False,
80 box_linewidth=1,
81 box_color="auto",
82 legend_text=None,
83 label_link_color="black",
84 **data
85 ):
86 self.start = start
87 self.end = end
88 self.strand = strand
89 self.label = label
90 self.color = color
91 self.linecolor = linecolor
92 self.data = data
93 self.thickness = thickness
94 self.linewidth = linewidth
95 self.box_linewidth = box_linewidth
96 self.box_color = box_color
97 self.label_link_color = label_link_color
98 self.fontdict = dict([("fontsize", 11)] + list((fontdict or {}).items()))
99 self.html = html
100 self.open_left = open_left
101 self.open_right = open_right
102 self.legend_text = legend_text
103
104 def split_in_two(self, x_coord=0):
105 """Return two features by cutting this feature at x_coord."""
106 copy1 = deepcopy(self)
107 copy2 = deepcopy(self)
108 copy1.end = x_coord
109 copy2.start = x_coord + 1
110 return copy1, copy2
111
112 def crop(self, window):
113 """Return a the fragment of the feature that is in the window.
114
115 If there is no overlap between the feature location and the window,
116 None is returned.
117 """
118 s, e = window
119 if (s > self.end) or (e < self.start):
120 return None
121 copy = deepcopy(self)
122 if s > self.start:
123 copy.start = s
124 copy.open_left = True
125 if e < self.end:
126 copy.end = e
127 copy.open_right = True
128 return copy
129
130 def overlaps_with(self, other):
131 """Return whether the feature's location overlaps with feature `other`"""
132 loc1, loc2 = (self.start, self.end), (other.start, other.end)
133 loc1, loc2 = sorted(loc1), sorted(loc2)
134 loc1, loc2 = sorted([loc1, loc2], key=lambda loc: loc[0])
135 return loc1[1] > loc2[0]
136
137 @property
138 def length(self):
139 """Return the length of the feature (end-start)"""
140 return abs(self.end - self.start)
141
142 @property
143 def x_center(self):
144 """Return the x-center of the feature, (start+end)/2"""
145 return 0.5 * (self.start + self.end - 1)
146
147 @staticmethod
148 def from_biopython_feature(feature, **props):
149 """Create a GraphicalFeature from a Biopython.Feature object."""
150 return GraphicFeature(
151 start=feature.location.start,
152 end=feature.location.end,
153 strand=feature.location.strand,
154 **props
155 )
156
157 def __repr__(self):
158 return ("GF(%(label)s, %(start)d-%(end)d " % self.__dict__) + (
159 ")" if self.strand is None else "(%d))" % self.strand
160 )