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