Package Bio :: Package Graphics :: Module DisplayRepresentation
[hide private]
[frames] | no frames]

Source Code for Module Bio.Graphics.DisplayRepresentation

  1  """Represent information for graphical display. 
  2   
  3  Classes in this module are designed to hold information in a way that 
  4  makes it easy to draw graphical figures. 
  5  """ 
  6  # reportlab 
  7  from reportlab.lib import colors 
  8   
  9  # local stuff 
 10  from Bio.Graphics.BasicChromosome import ChromosomeSegment 
 11  from Bio.Graphics.BasicChromosome import TelomereSegment 
 12   
 13  # --- constants 
 14  # This is a default color scheme based on the light spectrum. 
 15  # Based on my vague recollections from biology, this is our friend ROY G. BIV 
 16  RAINBOW_COLORS = {(1, 1)  : colors.violet, 
 17                    (2, 2)  : colors.indigo, 
 18                    (3, 3)  : colors.blue, 
 19                    (4, 4)  : colors.green, 
 20                    (5, 5)  : colors.yellow, 
 21                    (6, 6)  : colors.orange, 
 22                    (7, 20) : colors.red} 
 23   
 24   
25 -class ChromosomeCounts(object):
26 """Represent a chromosome with count information. 27 28 This is used to display information about counts along a chromosome. 29 The segments are expected to have different count information, which 30 will be displayed using a color scheme. 31 32 I envision using this class when you think that certain regions of 33 the chromosome will be especially abundant in the counts, and you 34 want to pick those out. 35 """
36 - def __init__(self, segment_names, color_scheme = RAINBOW_COLORS):
37 """Initialize a representation of chromosome counts. 38 39 Arguments: 40 41 o segment_names - An ordered list of all segment names along 42 the chromosome. The count and other information will be added to 43 these. 44 45 o color_scheme - A coloring scheme to use in the counts. This should 46 be a dictionary mapping count ranges to colors (specified in 47 reportlab.lib.colors). 48 """ 49 self._names = segment_names 50 self._count_info = {} 51 self._label_info = {} 52 self._scale_info = {} 53 for name in self._names: 54 self._count_info[name] = 0 55 self._label_info[name] = None 56 self._scale_info[name] = 1 57 58 self._color_scheme = color_scheme
59
60 - def add_count(self, segment_name, count = 1):
61 """Add counts to the given segment name. 62 63 Arguments: 64 65 o segment_name - The name of the segment we should add counts to. 66 If the name is not present, a KeyError will be raised. 67 68 o count - The counts to add the current segment. This defaults to 69 a single count. 70 """ 71 try: 72 self._count_info[segment_name] += count 73 except KeyError: 74 raise KeyError("Segment name %s not found." % segment_name)
75
76 - def scale_segment_value(self, segment_name, scale_value = None):
77 """Divide the counts for a segment by some kind of scale value. 78 79 This is useful if segments aren't represented by raw counts, but 80 are instead counts divided by some number. 81 """ 82 try: 83 self._count_info[segment_name] = \ 84 float(self._count_info[segment_name]) / float(scale_value) 85 except KeyError: 86 raise KeyError("Segment name %s not found." % segment_name)
87
88 - def add_label(self, segment_name, label):
89 """Add a label to a specfic segment. 90 91 Raises a KeyError is the specified segment name is not found. 92 """ 93 if segment_name in self._label_info: 94 self._label_info[segment_name] = label 95 else: 96 raise KeyError("Segment name %s not found." % segment_name)
97
98 - def set_scale(self, segment_name, scale):
99 """Set the scale for a specific chromosome segment. 100 101 By default all segments have the same scale -- this allows scaling 102 by the size of the segment. 103 104 Raises a KeyError is the specified segment name is not found. 105 """ 106 if segment_name in self._label_info: 107 self._scale_info[segment_name] = scale 108 else: 109 raise KeyError("Segment name %s not found." % segment_name)
110
111 - def get_segment_info(self):
112 """Retrieve the color and label info about the segments. 113 114 Returns a list consiting of two tuples specifying the counts and 115 label name for each segment. The list is ordered according to the 116 original listing of names. Labels are set as None if no label 117 was specified. 118 """ 119 order_info = [] 120 121 for seg_name in self._names: 122 order_info.append((self._count_info[seg_name], 123 self._label_info[seg_name])) 124 125 return order_info
126
127 - def fill_chromosome(self, chromosome):
128 """Add the collected segment information to a chromosome for drawing. 129 130 Arguments: 131 132 o chromosome - A Chromosome graphics object that we can add 133 chromosome segments to. 134 135 This creates ChromosomeSegment (and TelomereSegment) objects to 136 fill in the chromosome. The information is derived from the 137 label and count information, with counts transformed to the 138 specified color map. 139 140 Returns the chromosome with all of the segments added. 141 """ 142 for seg_num in range(len(self._names)): 143 is_end_segment = 0 144 # make the top and bottom telomeres 145 if seg_num == 0: 146 cur_segment = TelomereSegment() 147 is_end_segment = 1 148 elif seg_num == len(self._names) - 1: 149 cur_segment = TelomereSegment(1) 150 is_end_segment = 1 151 # otherwise, they are just regular segments 152 else: 153 cur_segment = ChromosomeSegment() 154 155 seg_name = self._names[seg_num] 156 if self._count_info[seg_name] > 0: 157 color = self._color_from_count(self._count_info[seg_name]) 158 cur_segment.fill_color = color 159 160 if self._label_info[seg_name] is not None: 161 cur_segment.label = self._label_info[seg_name] 162 163 # give end segments extra size so they look right 164 if is_end_segment: 165 cur_segment.scale = 3 166 else: 167 cur_segment.scale = self._scale_info[seg_name] 168 169 chromosome.add(cur_segment) 170 171 return chromosome
172
173 - def _color_from_count(self, count):
174 """Translate the given count into a color using the color scheme. 175 """ 176 for count_start, count_end in self._color_scheme: 177 if count >= count_start and count <= count_end: 178 return self._color_scheme[(count_start, count_end)] 179 180 # if we got here we didn't find a color for the count 181 raise ValueError("Count value %s was not found in the color scheme." 182 % count)
183