Mercurial > repos > cpt > cpt_linear_genome_plot
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 ) |