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