source: fact/tools/pyscripts/pyfact/plotters.py@ 15471

Last change on this file since 15471 was 14116, checked in by neise, 12 years ago
added sphinx automodule support. just 3 lines of self.__module__ = <modulename>
  • Property svn:executable set to *
File size: 12.8 KB
Line 
1#!/usr/bin/python -tt
2#
3# Werner Lustermann, Dominik Neise
4# ETH Zurich, TU Dortmund
5#
6# plotter.py
7
8import numpy as np
9import matplotlib.pyplot as plt
10import os.path
11import sys
12
13# this class was formerly called Plotter in the depricated
14# module plotter.py
15class SimplePlotter(object):
16 """ simple x-y plot """
17 def __init__(self, name, x, style = 'b', xlabel='x', ylabel='y'):
18 """ initialize the object """
19 self.__module__ = 'plotters'
20 self.name = name
21 self.fig = plt.figure()
22 self.line, = plt.plot(x, style)
23
24 plt.title(name)
25 plt.xlabel(xlabel)
26 plt.ylabel(ylabel)
27 plt.grid(True)
28
29 def __call__(self, ydata):
30 """ set ydata of plot """
31 plt.figure(self.fig.number)
32 plt.ylim( np.min(ydata), np.max(ydata) )
33 self.line.set_ydata(ydata)
34 plt.draw()
35
36class Plotter(object):
37 """ simple x-y plot """
38 def __init__(self, name, x=None, style = '.:', xlabel='x', ylabel='y', ion=True, grid=True, fname=None):
39 """ initialize the object """
40 self.__module__ = 'plotters'
41 self.name = name
42 self.x = x
43 self.style = style
44 self.xlabel = xlabel
45 self.ylabel = ylabel
46
47 #not sure if this should go here
48 if ion:
49 plt.ion()
50
51 self.figure = plt.figure()
52 self.fig_id = self.figure.number
53
54 plt.grid(grid)
55 self.grid = grid
56 self.fname = fname
57
58 def __call__(self, ydata, label=None):
59 """ set ydata of plot """
60 style = self.style
61
62 # make acitve and clear
63 plt.figure(self.fig_id)
64 plt.cla()
65
66 # the following if else stuff is horrible,
67 # but I want all those possibilities, .... still working on it.
68
69 # check if 1Dim oder 2Dim
70 ydata = np.array(ydata)
71 if ydata.ndim ==1:
72 if self.x==None:
73 plt.plot(ydata, self.style, label=label)
74 else:
75 plt.plot(self.x, ydata, self.style, label=label)
76 else:
77 for i in range(len(ydata)):
78 if self.x==None:
79 if label:
80 plt.plot(ydata[i], style, label=label[i])
81 else:
82 plt.plot(ydata[i], style)
83 else:
84 if label:
85 plt.plot(self.x, ydata[i], style, label=label[i])
86 else:
87 plt.plot(self.x, ydata[i], style)
88 plt.title(self.name)
89 plt.xlabel(self.xlabel)
90 plt.ylabel(self.ylabel)
91 if label:
92 plt.legend()
93
94 if self.fname != None:
95 plt.savefig(self.fname)
96
97 plt.grid(self.grid)
98 plt.draw()
99
100
101class CamPlotter(object):
102 """ plotting data color-coded into FACT-camera """
103 def __init__(self, name, ion=True, grid=True, fname=None, map_file_path = '../map_dn.txt', vmin=None, vmax=None):
104 """ initialize the object """
105 self.__module__ = 'plotters'
106 path = os.path.abspath(__file__)
107 path = os.path.dirname(path)
108 map_file_path = os.path.join(path, map_file_path)
109 if not os.path.isfile(map_file_path):
110 print 'not able to find file:', map_file_path
111 sys.exit(-2)
112
113 self.name = name
114 if ion:
115 plt.ion()
116
117 chid, y,x,ye,xe,yh,xh,softid,hardid = np.loadtxt(map_file_path ,unpack=True)
118
119 self.xe = xe
120 self.ye = ye
121
122 self.H = (6,0,30./180.*3.1415926)
123
124 self.figure = plt.figure(figsize=(6, 6), dpi=80)
125 self.fig_id = self.figure.number
126
127 self.grid = grid
128 self.fname = fname
129 self.vmin = vmin
130 self.vmax = vmax
131
132 def __call__(self, data, mask=None):
133 # define some shortcuts
134 xe = self.xe
135 ye = self.ye
136 H = self.H
137 name = self.name
138 grid = self.grid
139 vmin = self.vmin
140 vmax = self.vmax
141
142 # get the figure, clean it, and set it up nicely.
143 # maybe cleaning is not necessary and takes long, but
144 # I've got no time to test it at the moment.
145 plt.figure(self.fig_id)
146 plt.clf()
147 self.ax = self.figure.add_subplot(111, aspect='equal')
148 self.ax.axis([-22,22,-22,22])
149 self.ax.set_title(name)
150 self.ax.grid(grid)
151
152 # throw data into numpy array for simplicity
153 data = np.array(data)
154
155 #handle masked case specially
156 if mask!= None:
157 if len(mask)==0:
158 return
159
160 elif mask.dtype == bool and data.ndim ==1 and len(mask)==1440:
161 length = mask.sum()
162 mask = np.where(mask)[0]
163 mxe = np.empty( length )
164 mye = np.empty( length )
165 mdata = np.empty( length )
166 for i,chid in enumerate(mask):
167 #print i , chid
168 mxe[i] = xe[chid]
169 mye[i] = ye[chid]
170 mdata[i] = data[chid]
171 #print 'mxe', mxe, 'len', len(mxe)
172 #print 'mye', mye, 'len', len(mye)
173 #print 'mxe', mdata, 'len', len(mdata)
174
175 self.ax.axis([-22,22,-22,22])
176 self.ax.set_title(name)
177 self.ax.grid(grid)
178 # the next line is a stupid hack
179 # I plot invisible pixels, so that the axes show look ok.
180 # this must be possible differently, but I don't know how...
181 self.ax.scatter(xe,ye,s=25,alpha=0,marker=H)
182
183 result = self.ax.scatter(mxe,mye,s=25,alpha=1.,
184 c=mdata, marker=H, linewidths=0., vmin=vmin, vmax=vmax)
185 self.figure.colorbar( result, shrink=0.8, pad=-0.04 )
186 plt.draw()
187
188
189 elif mask.dtype == int and data.ndim ==1:
190 length = len(mask)
191 mxe = np.empty( length )
192 mye = np.empty( length )
193 mdata = np.empty( length )
194 for i,chid in enumerate(mask):
195 mxe[i] = xe[chid]
196 mye[i] = ye[chid]
197 mdata[i] = data[chid]
198
199 self.ax.axis([-22,22,-22,22])
200 self.ax.set_title(name)
201 self.ax.grid(grid)
202 # the next line is a stupid hack
203 # I plot invisible pixels, so that the axes look ok.
204 # this must be possible differently, but I don't know how...
205 self.ax.scatter(xe,ye,s=25,alpha=0,marker=H)
206
207 result = self.ax.scatter(mxe,mye,s=25,alpha=1.,
208 c=mdata, marker=H, linewidths=0., vmin=vmin, vmax=vmax)
209 self.figure.colorbar( result, shrink=0.8, pad=-0.04 )
210 plt.draw()
211
212 else:
213 print "there is a mask, but I don't know how to treat it!!!"
214 sys.exit(-1)
215 else: # i.e. when mask is None
216 # handle 1D and 2D case differently
217 if data.ndim == 1 and len(data)==1440:
218 result = self.ax.scatter(xe,ye,s=25,alpha=1,
219 c=data, marker=H, linewidths=0., vmin=vmin, vmax=vmax)
220 self.figure.colorbar( result, shrink=0.8, pad=-0.04 )
221 plt.draw()
222
223 elif data.ndim == 2 and data.shape[0] == 2 and data.shape[1] <=1440:
224 # I assume the first row of data, contains the CHIDs
225 # and the 2nd row contains the actual data.
226 chids = data[0]
227 # check if there are double chids in chids
228 if len(chids)!=len(set(chids)):
229 print 'warning: there are doubled chids in input data',
230 print 'you might want to plot something else, but I plot it anyway...'
231 print chids
232 data = data[1]
233 # now I have to mask the xe, and ye vectors accordingly
234 mxe = np.empty( len(chids) )
235 mye = np.empty( len(chids) )
236 for i,chid in enumerate(chids):
237 mxe[i] = xe[chid]
238 mye[i] = ye[chid]
239
240 # check if I did it right
241 if len(mxe)!=len(data) or len(mye)!=len(data):
242 print 'the masking did not work:'
243 print 'len(mxe)', len(mxe)
244 print 'len(mye)', len(mye)
245 print 'len(data)', len(data)
246
247 self.ax.axis([-22,22,-22,22])
248 self.ax.set_title(name)
249 self.ax.grid(grid)
250 # the next line is a stupid hack
251 # I plot invisible pixels, so that the axes show look ok.
252 # this must be possible differently, but I don't know how...
253 self.ax.scatter(xe,ye,s=25,alpha=0,marker=H)
254
255 result = self.ax.scatter(mxe,mye,s=25,alpha=1.,
256 c=data, marker=H, linewidths=0., vmin=vmin, vmax=vmax)
257 self.figure.colorbar( result, shrink=0.8, pad=-0.04 )
258 plt.draw()
259
260 else:
261 print 'CamPlotter call input data has bad format'
262 print 'data.ndim', data.ndim
263 print 'data.shape', data.shape
264 print 'data:----------------------------------'
265 print data
266
267
268
269
270class HistPlotter(object):
271
272 def __init__(self, name, bins, range, grid=True, ion=True):
273 """ initialize the object """
274 self.bins = bins
275 self.range = range
276 self.name = name
277 self.figure = plt.figure()
278 self.fig_id = self.figure.number
279 self.grid = grid
280
281 if ion:
282 plt.ion()
283
284 def __call__(self, ydata, label=None, log=False):
285 plt.figure(self.fig_id)
286 plt.cla()
287
288 bins = self.bins
289 range = self.range
290 grid = self.grid
291
292 ydata = np.array(ydata)
293
294 if ydata.ndim > 1:
295 ydata = ydata.flatten()
296 if label:
297 plt.hist(ydata, bins, range, label=label, log=log)
298 plt.legend()
299 else:
300 plt.hist(ydata, bins, range, log=log)
301
302 plt.title(self.name)
303
304 plt.draw()
305
306def _test_SimplePlotter():
307 """ test of maintaining two independant plotter instances """
308 plt.ion()
309
310 x = np.linspace(0., 10.)
311 plot1 = SimplePlotter('plot1', x, 'r')
312 print 'plot1.fig.number: ', plot1.fig.number
313 plot2 = SimplePlotter('plot2', x, 'g.')
314 print 'plot2.fig.number: ', plot2.fig.number
315
316 plot1(np.sin(x) * 7.)
317 plot2(x*x)
318
319 raw_input('next')
320
321 plot1(np.cos(x) * 3.)
322 plot2(x)
323
324 raw_input('next')
325
326
327def _test_Plotter():
328 """ test of maintaining two independant plotter instances
329 with different examples for init and call
330 """
331 x = np.linspace(0., 2*np.pi , 100)
332 plot1 = Plotter('plot1', x, 'r.:')
333 plot2 = Plotter('plot2')
334
335 y1 = np.sin(x) * 7
336 plot1(y1)
337
338 number_of_graphs_in_plot2 = 3
339 no = number_of_graphs_in_plot2 # short form
340
341 # this is where you do your analysis...
342 y2 = np.empty( (no, len(x)) ) # prepare some space
343 y2_labels = [] # prepare labels
344 for k in range(no):
345 y2[k] = np.sin( (k+1)*x )
346 y2_labels.append('sin(%d*x)' % (k+1) )
347
348 # plot the result of your analysis
349 plot2(y2, y2_labels)
350 raw_input('next') # do not forget this line, or your graph is lost
351
352 plot1(np.cos(x) * 3.)
353 plot2.name += ' without labels!!!' # changing titles 'on the fly' is possible
354 plot2(y2)
355 raw_input('next') # DO NOT forget
356
357
358def _test_CamPlotter():
359 """ test of CamPlotter """
360
361 c1 = np.array(range(20))
362 chids1 = np.empty( len(c1) , dtype=int)
363 for i in range(len(chids1)-2):
364 chids1[i] = np.random.randint(1440)
365 chids1[-1] = 15
366 chids1[-2] = 15
367
368 c2 = np.linspace(0., 1., num=1440)
369 plot1 = CamPlotter('plot1')
370 plot2 = CamPlotter('plot2')
371
372 plot1( (chids1,c1) )
373 plot2(c2)
374 raw_input('next')
375
376def _test_HistPlotter():
377 """ test of the HistPlotter """
378 plt.ion()
379
380 data = np.random.randn(1000)
381 hp = HistPlotter('test hist plotter',34, (-5,4))
382
383 hp(data, 'test-label')
384 raw_input('next')
385
386if __name__ == '__main__':
387 """ test the class """
388 print ' testing SimplePlotter'
389 _test_SimplePlotter()
390 print ' testing Plotter'
391 _test_Plotter()
392 print 'testing CamPlotter ... testing what happens if doubled IDs in mask'
393 _test_CamPlotter()
394 print 'testing basic HistPlotter functionality'
395 _test_HistPlotter()
396
Note: See TracBrowser for help on using the repository browser.