comparison CADrawer.py @ 46:d83a72eec954

Forgot to add these. Needed for Chapter 6.
author Brian Neal <bgneal@gmail.com>
date Thu, 25 Jul 2013 21:27:36 -0500
parents
children
comparison
equal deleted inserted replaced
45:1804f09a7adb 46:d83a72eec954
1 """ Code example from Complexity and Computation, a book about
2 exploring complexity science with Python. Available free from
3
4 http://greenteapress.com/complexity
5
6 Copyright 2011 Allen B. Downey.
7 Distributed under the GNU General Public License at gnu.org/licenses/gpl.html.
8 """
9
10 import numpy
11
12
13 class UnimplementedMethodException(Exception):
14 """Used to indicate that a child class has not implemented an
15 abstract method."""
16
17
18 class Drawer(object):
19 """Drawer is an abstract class that should not be instantiated.
20 It defines the interface for a CA drawer; child classes of Drawer
21 should implement draw, show and save.
22
23 If draw_array is not overridden, the child class should provide
24 draw_cell.
25 """
26 def __init__(self):
27 msg = 'CADrawer is an abstract type and should not be instantiated.'
28 raise UnimplementedMethodException, msg
29
30 def draw(self, ca):
31 """Draws a representation of cellular automaton (CA).
32 This function generally has no visible effect."""
33 raise UnimplementedMethodException
34
35 def draw_array(self, a):
36 """Iterate through array (a) and draws any non-zero cells."""
37 for i in xrange(self.rows):
38 for j in xrange(self.cols):
39 if a[i,j]:
40 self.draw_cell(j, self.rows-i-1)
41
42 def draw_cell(self, ca):
43 """Draws a single cell.
44 Not required for all implementations."""
45 raise UnimplementedMethodException
46
47 def show(self):
48 """Displays the representation on the screen, if possible."""
49 raise UnimplementedMethodException
50
51 def save(self, filename):
52 """Saves the representation of the CA in filename."""
53 raise UnimplementedMethodException
54
55
56 class PyplotDrawer(Drawer):
57 """Implementation of Drawer using matplotlib."""
58
59 def __init__(self):
60 # we only need to import pyplot if a PyplotDrawer
61 # gets instantiated
62 global pyplot
63 import matplotlib.pyplot as pyplot
64
65 def draw(self, ca, start=0, end=None):
66 """Draws the CA using pyplot.pcolor."""
67 pyplot.gray()
68 a = ca.get_array(start, end)
69 rows, cols = a.shape
70
71 # flipud puts the first row at the top;
72 # negating it makes the non-zero cells black.
73 pyplot.pcolor(-numpy.flipud(a))
74 pyplot.axis([0, cols, 0, rows])
75
76 # empty lists draw no ticks
77 pyplot.xticks([])
78 pyplot.yticks([])
79
80 def show(self):
81 """display the pseudocolor representation of the CA"""
82 pyplot.show()
83
84 def save(self, filename='ca.png'):
85 """save the pseudocolor representation of the CA in (filename)."""
86 pyplot.savefig(filename)
87
88
89 class PILDrawer(Drawer):
90 """Implementation of Drawer using PIL and Swampy."""
91
92 def __init__(self, csize=4, color='black'):
93 # we only need to import these modules if a PILDrawer
94 # gets instantiated
95 global Image, ImageDraw, ImageTk, Gui
96 import Image
97 import ImageDraw
98 import ImageTk
99 try:
100 import Gui
101 except ImportError:
102 import swampy.Gui
103 self.csize = csize
104 self.color = color
105
106 def draw(self, ca, start=0, end=None):
107 a = ca.get_array(start, end)
108 self.rows, self.cols = a.shape
109 size = [self.cols * self.csize, self.rows * self.csize]
110
111 self.gui = Gui.Gui()
112 self.button = self.gui.bu(command=self.gui.quit)
113
114 self.image = Image.new(mode='1', size=size, color='white')
115 self.drawable = ImageDraw.Draw(self.image)
116 self.draw_array(numpy.flipud(a))
117
118 def draw_cell(self, i, j):
119 size = self.csize
120 x, y = i*size, j*size
121 self.drawable.rectangle([x, y, x+size, y+size], fill=self.color)
122
123 def show(self):
124 self.tkpi = ImageTk.PhotoImage(self.image)
125 self.button.config(image=self.tkpi)
126 self.gui.mainloop()
127
128 def save(self, filename='ca.gif'):
129 self.image.save(filename)
130
131
132 class EPSDrawer(Drawer):
133 """Implementation of Drawer using encapsulated Postscript (EPS)."""
134
135 def __init__(self):
136 self.cells = []
137
138 def draw(self, ca, start=0, end=None):
139 a = ca.get_array(start, end)
140 self.rows, self.cols = a.shape
141 self.draw_array(a)
142
143 def draw_cell(self, i, j):
144 self.cells.append((i,j))
145
146 def show(self):
147 raise UnimplementedMethodException
148
149 def save(self, filename='ca.eps'):
150 fp = open(filename, 'w')
151 self.print_header(fp)
152 self.print_outline(fp)
153 self.print_cells(fp)
154 self.print_footer(fp)
155
156 def print_cells(self, fp):
157 for i, j in self.cells:
158 fp.write('%s %s c\n' % (i, j))
159
160 def print_header(self, fp, size=0.9):
161 fp.write('%!PS-Adobe-3.0 EPSF-3.0\n')
162 fp.write('%%%%BoundingBox: -2 -2 %s %s\n' % (self.cols+2, self.rows+2))
163
164 fp.write('/c {\n')
165 fp.write(' newpath moveto\n')
166 fp.write(' 0 %g rlineto\n' % size)
167 fp.write(' %g 0 rlineto\n' % size)
168 fp.write(' 0 -%g rlineto\n' % size)
169 fp.write(' closepath fill\n')
170 fp.write('} def\n')
171
172 def print_outline(self, fp):
173 fp.write('newpath 0.1 setlinewidth 0 0 moveto\n')
174 fp.write('0 %s rlineto\n' % self.rows)
175 fp.write('%s 0 rlineto\n' % self.cols)
176 fp.write('0 -%s rlineto\n' % self.rows)
177 fp.write('closepath stroke\n')
178
179 def print_footer(self, fp):
180 fp.write('%%EOF\n')
181