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

Source Code for Module Bio.Graphics.Comparative

  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  """Plots to compare information between different sources. 
  7   
  8  This file contains high level plots which are designed to be used to 
  9  compare different types of information. The most basic example is comparing 
 10  two variables in a traditional scatter plot. 
 11  """ 
 12  # reportlab 
 13  from reportlab.lib import colors 
 14  from reportlab.graphics.charts.lineplots import LinePlot 
 15  from reportlab.lib.pagesizes import letter 
 16  from reportlab.lib.units import inch 
 17   
 18  from reportlab.graphics.shapes import Drawing, String 
 19  from reportlab.graphics.charts.markers import makeEmptySquare, makeFilledSquare 
 20  from reportlab.graphics.charts.markers import makeFilledDiamond, makeSmiley 
 21  from reportlab.graphics.charts.markers import makeFilledCircle, makeEmptyCircle 
 22   
 23  from Bio.Graphics import _write 
 24   
 25   
26 -class ComparativeScatterPlot(object):
27 """Display a scatter-type plot comparing two different kinds of info. 28 29 Attributes; 30 - display_info - a 2D list of the information we'll be outputting. Each 31 top level list is a different data type, and each data point is a 32 two-tuple of the coordinates of a point. 33 34 So if you had two distributions of points, it should look like:: 35 36 display_info = [[(1, 2), (3, 4)], 37 [(5, 6), (7, 8)]] 38 39 If everything is just one set of points, display_info can look like:: 40 41 display_info = [[(1, 2), (3, 4), (5, 6)]] 42 43 """ 44
45 - def __init__(self, output_format='pdf'):
46 """Initialize.""" 47 # customizable attributes 48 self.number_of_columns = 1 49 self.page_size = letter 50 self.title_size = 20 51 52 self.output_format = output_format 53 54 # the information we'll be writing 55 self.display_info = [] 56 57 # initial colors and shapes used for drawing points 58 self.color_choices = [colors.red, colors.green, colors.blue, 59 colors.yellow, colors.orange, colors.black] 60 self.shape_choices = [makeFilledCircle, makeEmptySquare, 61 makeFilledDiamond, makeFilledSquare, 62 makeEmptyCircle, makeSmiley]
63
64 - def draw_to_file(self, output_file, title):
65 """Write the comparative plot to a file. 66 67 Arguments: 68 - output_file - The name of the file to output the information to, 69 or a handle to write to. 70 - title - A title to display on the graphic. 71 72 """ 73 width, height = self.page_size 74 cur_drawing = Drawing(width, height) 75 76 self._draw_title(cur_drawing, title, width, height) 77 78 start_x = inch * .5 79 end_x = width - inch * .5 80 end_y = height - 1.5 * inch 81 start_y = .5 * inch 82 self._draw_scatter_plot(cur_drawing, start_x, start_y, end_x, end_y) 83 84 return _write(cur_drawing, output_file, self.output_format)
85
86 - def _draw_title(self, cur_drawing, title, width, height):
87 """Add a title to the page we are outputting.""" 88 title_string = String(width / 2, height - inch, title) 89 title_string.fontName = 'Helvetica-Bold' 90 title_string.fontSize = self.title_size 91 title_string.textAnchor = "middle" 92 93 cur_drawing.add(title_string)
94
95 - def _draw_scatter_plot(self, cur_drawing, x_start, y_start, 96 x_end, y_end):
97 """Draw a scatter plot on the drawing with the given coordinates.""" 98 scatter_plot = LinePlot() 99 100 # set the dimensions of the scatter plot 101 scatter_plot.x = x_start 102 scatter_plot.y = y_start 103 scatter_plot.width = abs(x_start - x_end) 104 scatter_plot.height = abs(y_start - y_end) 105 106 scatter_plot.data = self.display_info 107 108 scatter_plot.joinedLines = 0 109 110 # set the axes of the plot 111 x_min, x_max, y_min, y_max = self._find_min_max(self.display_info) 112 scatter_plot.xValueAxis.valueMin = x_min 113 scatter_plot.xValueAxis.valueMax = x_max 114 scatter_plot.xValueAxis.valueStep = (x_max - x_min) / 10.0 115 116 scatter_plot.yValueAxis.valueMin = y_min 117 scatter_plot.yValueAxis.valueMax = y_max 118 scatter_plot.yValueAxis.valueStep = (y_max - y_min) / 10.0 119 120 self._set_colors_and_shapes(scatter_plot, self.display_info) 121 122 cur_drawing.add(scatter_plot)
123
124 - def _set_colors_and_shapes(self, scatter_plot, display_info):
125 """Set the colors and shapes of the points displayed. 126 127 By default this just sets all of the points according to the order 128 of colors and shapes defined in self.color_choices and 129 self.shape_choices. The first 5 shapes and colors are unique, the 130 rest of them are just set to the same color and shape (since I 131 ran out of shapes!). 132 133 You can change how this function works by either changing the 134 values of the color_choices and shape_choices attributes, or 135 by inheriting from this class and overriding this function. 136 """ 137 for value_num in range(len(display_info)): 138 # if we have unique colors, add them 139 if (value_num + 1) < len(self.color_choices): 140 scatter_plot.lines[value_num].strokeColor = \ 141 self.color_choices[value_num] 142 scatter_plot.lines[value_num].symbol = \ 143 self.shape_choices[value_num] 144 # otherwise just use the last number 145 else: 146 scatter_plot.lines[value_num].strokeColor = \ 147 self.color_choices[-1] 148 scatter_plot.lines[value_num].symbol = \ 149 self.shape_choices[-1]
150
151 - def _find_min_max(self, info):
152 """Find min and max for x and y coordinates in the given data.""" 153 x_min = info[0][0][0] 154 x_max = info[0][0][0] 155 y_min = info[0][0][1] 156 y_max = info[0][0][1] 157 158 for two_d_list in info: 159 for x, y in two_d_list: 160 if x > x_max: 161 x_max = x 162 if x < x_min: 163 x_min = x 164 if y > y_max: 165 y_max = y 166 if y < y_min: 167 y_min = y 168 169 return x_min, x_max, y_min, y_max
170