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

Source Code for Module Bio.Graphics.GenomeDiagram._Graph

  1  # Copyright 2003-2008 by Leighton Pritchard.  All rights reserved. 
  2  # Revisions copyright 2008-2009 by Peter Cock. 
  3  # This code is part of the Biopython distribution and governed by its 
  4  # license.  Please see the LICENSE file that should have been included 
  5  # as part of this package. 
  6  # 
  7  # Contact:       Leighton Pritchard, Scottish Crop Research Institute, 
  8  #                Invergowrie, Dundee, Scotland, DD2 5DA, UK 
  9  #                L.Pritchard@scri.ac.uk 
 10  ################################################################################ 
 11   
 12  """Graph module. 
 13   
 14  Provides: 
 15   - GraphData - Contains data from which a graph will be drawn, and 
 16     information about its presentation 
 17   
 18  For drawing capabilities, this module uses reportlab to draw and write 
 19  the diagram: http://www.reportlab.com 
 20  """ 
 21   
 22  # ReportLab imports 
 23  from __future__ import print_function 
 24   
 25  from reportlab.lib import colors 
 26   
 27  from math import sqrt 
 28   
 29   
30 -class GraphData(object):
31 """Graph Data. 32 33 Attributes: 34 - id Unique identifier for the data 35 - data Dictionary of describing the data, keyed by position 36 - name String describing the data 37 - style String ('bar', 'heat', 'line') describing how to draw the data 38 - poscolor colors.Color for drawing high (some styles) or all 39 values 40 - negcolor colors.Color for drawing low values (some styles) 41 - linewidth Int, thickness to draw the line in 'line' styles 42 43 """ 44
45 - def __init__(self, id=None, data=None, name=None, style='bar', 46 color=colors.lightgreen, altcolor=colors.darkseagreen, 47 center=None, colour=None, altcolour=None):
48 """Initialize. 49 50 Arguments: 51 - id Unique ID for the graph 52 - data List of (position, value) tuples 53 - name String describing the graph 54 - style String describing the presentation style ('bar', 'line', 55 'heat') 56 - color colors.Color describing the color to draw all or the 57 'high' (some styles) values (overridden by backwards 58 compatible argument with UK spelling, colour). 59 - altcolor colors.Color describing the color to draw the 'low' 60 values (some styles only) (overridden by backwards 61 compatible argument with UK spelling, colour). 62 - center Value at which x-axis crosses y-axis. 63 64 """ 65 # Let the UK spelling (colour) override the USA spelling (color) 66 if colour is not None: 67 color = colour 68 if altcolour is not None: 69 altcolor = altcolour 70 71 self.id = id # Unique identifier for the graph 72 self.data = {} # holds values, keyed by sequence position 73 if data is not None: 74 self.set_data(data) 75 self.name = name # Descriptive string 76 77 # Attributes describing how the graph will be drawn 78 self.style = style # One of 'bar', 'heat' or 'line' 79 self.poscolor = color # Color to draw all, or 'high' values 80 self.negcolor = altcolor # Color to draw 'low' values 81 self.linewidth = 2 # linewidth to use in line graphs 82 self.center = center # value at which x-axis crosses y-axis
83
84 - def set_data(self, data):
85 """Add data as a list of (position, value) tuples.""" 86 for (pos, val) in data: # Fill data dictionary 87 self.data[pos] = val
88
89 - def get_data(self):
90 """Return data as a list of sorted (position, value) tuples.""" 91 data = [] 92 for xval in self.data: 93 yval = self.data[xval] 94 data.append((xval, yval)) 95 data.sort() 96 return data
97
98 - def add_point(self, point):
99 """Add a single point to the set of data as a (position, value) tuple.""" 100 pos, val = point 101 self.data[pos] = val
102
103 - def quartiles(self):
104 """Return (minimum, lowerQ, medianQ, upperQ, maximum) values as tuple.""" 105 data = sorted(self.data.values()) 106 datalen = len(data) 107 return(data[0], data[datalen // 4], data[datalen // 2], 108 data[3 * datalen // 4], data[-1])
109
110 - def range(self):
111 """Return range of data as (start, end) tuple. 112 113 Returns the range of the data, i.e. its start and end points on 114 the genome as a (start, end) tuple. 115 """ 116 positions = sorted(self.data) # i.e. dict keys 117 # Return first and last positions in graph 118 # print len(self.data) 119 return (positions[0], positions[-1])
120
121 - def mean(self):
122 """Return the mean value for the data points (float).""" 123 data = list(self.data.values()) 124 sum = 0. 125 for item in data: 126 sum += float(item) 127 return sum / len(data)
128
129 - def stdev(self):
130 """Return the sample standard deviation for the data (float).""" 131 data = list(self.data.values()) 132 m = self.mean() 133 runtotal = 0. 134 for entry in data: 135 runtotal += float((entry - m) ** 2) 136 # This is sample standard deviation; population stdev would involve 137 # division by len(data), rather than len(data)-1 138 return sqrt(runtotal / (len(data) - 1))
139
140 - def __len__(self):
141 """Return the number of points in the data set.""" 142 return len(self.data)
143
144 - def __getitem__(self, index):
145 """Return data value(s) at the given position. 146 147 Given an integer representing position on the sequence 148 returns a float - the data value at the passed position. 149 150 If a slice, returns graph data from the region as a list or 151 (position, value) tuples. Slices with step are not supported. 152 """ 153 if isinstance(index, int): 154 return self.data[index] 155 elif isinstance(index, slice): 156 # TODO - Why does it treat the end points both as inclusive? 157 # This doesn't match Python norms does it? 158 low = index.start 159 high = index.stop 160 if index.step is not None and index.step != 1: 161 raise ValueError 162 outlist = [] 163 for pos in sorted(self.data): 164 if pos >= low and pos <= high: 165 outlist.append((pos, self.data[pos])) 166 return outlist 167 else: 168 raise TypeError("Need an integer or a slice")
169
170 - def __str__(self):
171 """Return a string describing the graph data.""" 172 outstr = ["\nGraphData: %s, ID: %s" % (self.name, self.id)] 173 outstr.append("Number of points: %d" % len(self.data)) 174 outstr.append("Mean data value: %s" % self.mean()) 175 outstr.append("Sample SD: %.3f" % self.stdev()) 176 outstr.append("Minimum: %s\n1Q: %s\n2Q: %s\n3Q: %s\nMaximum: %s" % self.quartiles()) 177 outstr.append("Sequence Range: %s..%s" % self.range()) 178 return "\n".join(outstr)
179