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