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

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