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

Source Code for Module Bio.Graphics.DisplayRepresentation

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