##// END OF EJS Templates
Add interactive change of CMAP and localtime support
jespinoza -
r1071:0950cde3ae87
parent child
Show More
@@ -1,783 +1,819
1
1
2 import os
2 import os
3 import time
3 import time
4 import glob
4 import glob
5 import datetime
5 import datetime
6 from multiprocessing import Process
6 from multiprocessing import Process
7
7
8 import zmq
8 import zmq
9 import numpy
9 import numpy
10 import matplotlib
10 import matplotlib
11 import matplotlib.pyplot as plt
11 import matplotlib.pyplot as plt
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
14
14
15 from schainpy.model.proc.jroproc_base import Operation
15 from schainpy.model.proc.jroproc_base import Operation
16 from schainpy.utils import log
16 from schainpy.utils import log
17
17
18 func = lambda x, pos: ('%s') %(datetime.datetime.fromtimestamp(x).strftime('%H:%M'))
18 jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90]
19 blu_values = matplotlib.pyplot.get_cmap("seismic_r", 20)(numpy.arange(20))[10:15]
20 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list("jro", numpy.vstack((blu_values, jet_values)))
21 matplotlib.pyplot.register_cmap(cmap=ncmap)
19
22
20 d1970 = datetime.datetime(1970, 1, 1)
23 func = lambda x, pos: '{}'.format(datetime.datetime.fromtimestamp(x).strftime('%H:%M'))
21
24
25 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
26
27 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'RdBu_r', 'seismic')]
22
28
23 class PlotData(Operation, Process):
29 class PlotData(Operation, Process):
24 '''
30 '''
25 Base class for Schain plotting operations
31 Base class for Schain plotting operations
26 '''
32 '''
27
33
28 CODE = 'Figure'
34 CODE = 'Figure'
29 colormap = 'jro'
35 colormap = 'jro'
30 bgcolor = 'white'
36 bgcolor = 'white'
31 CONFLATE = False
37 CONFLATE = False
32 __MAXNUMX = 80
38 __MAXNUMX = 80
33 __missing = 1E30
39 __missing = 1E30
34
40
35 def __init__(self, **kwargs):
41 def __init__(self, **kwargs):
36
42
37 Operation.__init__(self, plot=True, **kwargs)
43 Operation.__init__(self, plot=True, **kwargs)
38 Process.__init__(self)
44 Process.__init__(self)
39 self.kwargs['code'] = self.CODE
45 self.kwargs['code'] = self.CODE
40 self.mp = False
46 self.mp = False
41 self.data = None
47 self.data = None
42 self.isConfig = False
48 self.isConfig = False
43 self.figures = []
49 self.figures = []
44 self.axes = []
50 self.axes = []
45 self.cb_axes = []
51 self.cb_axes = []
46 self.localtime = kwargs.pop('localtime', True)
52 self.localtime = kwargs.pop('localtime', True)
47 self.show = kwargs.get('show', True)
53 self.show = kwargs.get('show', True)
48 self.save = kwargs.get('save', False)
54 self.save = kwargs.get('save', False)
49 self.colormap = kwargs.get('colormap', self.colormap)
55 self.colormap = kwargs.get('colormap', self.colormap)
50 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
56 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
51 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
57 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
52 self.colormaps = kwargs.get('colormaps', None)
58 self.colormaps = kwargs.get('colormaps', None)
53 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
59 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
54 self.showprofile = kwargs.get('showprofile', False)
60 self.showprofile = kwargs.get('showprofile', False)
55 self.title = kwargs.get('wintitle', self.CODE.upper())
61 self.title = kwargs.get('wintitle', self.CODE.upper())
56 self.cb_label = kwargs.get('cb_label', None)
62 self.cb_label = kwargs.get('cb_label', None)
57 self.cb_labels = kwargs.get('cb_labels', None)
63 self.cb_labels = kwargs.get('cb_labels', None)
58 self.xaxis = kwargs.get('xaxis', 'frequency')
64 self.xaxis = kwargs.get('xaxis', 'frequency')
59 self.zmin = kwargs.get('zmin', None)
65 self.zmin = kwargs.get('zmin', None)
60 self.zmax = kwargs.get('zmax', None)
66 self.zmax = kwargs.get('zmax', None)
61 self.zlimits = kwargs.get('zlimits', None)
67 self.zlimits = kwargs.get('zlimits', None)
62 self.xmin = kwargs.get('xmin', None)
68 self.xmin = kwargs.get('xmin', None)
63 if self.xmin is not None:
64 self.xmin += 5
65 self.xmax = kwargs.get('xmax', None)
69 self.xmax = kwargs.get('xmax', None)
66 self.xrange = kwargs.get('xrange', 24)
70 self.xrange = kwargs.get('xrange', 24)
67 self.ymin = kwargs.get('ymin', None)
71 self.ymin = kwargs.get('ymin', None)
68 self.ymax = kwargs.get('ymax', None)
72 self.ymax = kwargs.get('ymax', None)
69 self.xlabel = kwargs.get('xlabel', None)
73 self.xlabel = kwargs.get('xlabel', None)
70 self.__MAXNUMY = kwargs.get('decimation', 100)
74 self.__MAXNUMY = kwargs.get('decimation', 100)
71 self.showSNR = kwargs.get('showSNR', False)
75 self.showSNR = kwargs.get('showSNR', False)
72 self.oneFigure = kwargs.get('oneFigure', True)
76 self.oneFigure = kwargs.get('oneFigure', True)
73 self.width = kwargs.get('width', None)
77 self.width = kwargs.get('width', None)
74 self.height = kwargs.get('height', None)
78 self.height = kwargs.get('height', None)
75 self.colorbar = kwargs.get('colorbar', True)
79 self.colorbar = kwargs.get('colorbar', True)
76 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
80 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
77 self.titles = ['' for __ in range(16)]
81 self.titles = ['' for __ in range(16)]
78
82
79 def __setup(self):
83 def __setup(self):
80 '''
84 '''
81 Common setup for all figures, here figures and axes are created
85 Common setup for all figures, here figures and axes are created
82 '''
86 '''
83
87
84 self.setup()
88 self.setup()
85
89
90 self.time_label = 'LT' if self.localtime else 'UTC'
91
86 if self.width is None:
92 if self.width is None:
87 self.width = 8
93 self.width = 8
88
94
89 self.figures = []
95 self.figures = []
90 self.axes = []
96 self.axes = []
91 self.cb_axes = []
97 self.cb_axes = []
92 self.pf_axes = []
98 self.pf_axes = []
93 self.cmaps = []
99 self.cmaps = []
94
100
95 size = '15%' if self.ncols==1 else '30%'
101 size = '15%' if self.ncols==1 else '30%'
96 pad = '4%' if self.ncols==1 else '8%'
102 pad = '4%' if self.ncols==1 else '8%'
97
103
98 if self.oneFigure:
104 if self.oneFigure:
99 if self.height is None:
105 if self.height is None:
100 self.height = 1.4*self.nrows + 1
106 self.height = 1.4*self.nrows + 1
101 fig = plt.figure(figsize=(self.width, self.height),
107 fig = plt.figure(figsize=(self.width, self.height),
102 edgecolor='k',
108 edgecolor='k',
103 facecolor='w')
109 facecolor='w')
104 self.figures.append(fig)
110 self.figures.append(fig)
105 for n in range(self.nplots):
111 for n in range(self.nplots):
106 ax = fig.add_subplot(self.nrows, self.ncols, n+1)
112 ax = fig.add_subplot(self.nrows, self.ncols, n+1)
107 ax.tick_params(labelsize=8)
113 ax.tick_params(labelsize=8)
108 ax.firsttime = True
114 ax.firsttime = True
115 ax.index = 0
109 self.axes.append(ax)
116 self.axes.append(ax)
110 if self.showprofile:
117 if self.showprofile:
111 cax = self.__add_axes(ax, size=size, pad=pad)
118 cax = self.__add_axes(ax, size=size, pad=pad)
112 cax.tick_params(labelsize=8)
119 cax.tick_params(labelsize=8)
113 self.pf_axes.append(cax)
120 self.pf_axes.append(cax)
114 else:
121 else:
115 if self.height is None:
122 if self.height is None:
116 self.height = 3
123 self.height = 3
117 for n in range(self.nplots):
124 for n in range(self.nplots):
118 fig = plt.figure(figsize=(self.width, self.height),
125 fig = plt.figure(figsize=(self.width, self.height),
119 edgecolor='k',
126 edgecolor='k',
120 facecolor='w')
127 facecolor='w')
121 ax = fig.add_subplot(1, 1, 1)
128 ax = fig.add_subplot(1, 1, 1)
122 ax.tick_params(labelsize=8)
129 ax.tick_params(labelsize=8)
123 ax.firsttime = True
130 ax.firsttime = True
131 ax.index = 0
124 self.figures.append(fig)
132 self.figures.append(fig)
125 self.axes.append(ax)
133 self.axes.append(ax)
126 if self.showprofile:
134 if self.showprofile:
127 cax = self.__add_axes(ax, size=size, pad=pad)
135 cax = self.__add_axes(ax, size=size, pad=pad)
128 cax.tick_params(labelsize=8)
136 cax.tick_params(labelsize=8)
129 self.pf_axes.append(cax)
137 self.pf_axes.append(cax)
130
138
131 for n in range(self.nrows):
139 for n in range(self.nrows):
132 if self.colormaps is not None:
140 if self.colormaps is not None:
133 cmap = plt.get_cmap(self.colormaps[n])
141 cmap = plt.get_cmap(self.colormaps[n])
134 else:
142 else:
135 cmap = plt.get_cmap(self.colormap)
143 cmap = plt.get_cmap(self.colormap)
136 cmap.set_bad(self.bgcolor, 1.)
144 cmap.set_bad(self.bgcolor, 1.)
137 self.cmaps.append(cmap)
145 self.cmaps.append(cmap)
138
146
147 for fig in self.figures:
148 fig.canvas.mpl_connect('key_press_event', self.event_key_press)
149
150 def event_key_press(self, event):
151 '''
152 '''
153
154 for ax in self.axes:
155 if ax == event.inaxes:
156 if event.key == 'down':
157 ax.index += 1
158 elif event.key == 'up':
159 ax.index -= 1
160 if ax.index < 0:
161 ax.index = len(CMAPS) - 1
162 elif ax.index == len(CMAPS):
163 ax.index = 0
164 cmap = CMAPS[ax.index]
165 ax.cbar.set_cmap(cmap)
166 ax.cbar.draw_all()
167 ax.plt.set_cmap(cmap)
168 ax.cbar.patch.figure.canvas.draw()
169
139 def __add_axes(self, ax, size='30%', pad='8%'):
170 def __add_axes(self, ax, size='30%', pad='8%'):
140 '''
171 '''
141 Add new axes to the given figure
172 Add new axes to the given figure
142 '''
173 '''
143 divider = make_axes_locatable(ax)
174 divider = make_axes_locatable(ax)
144 nax = divider.new_horizontal(size=size, pad=pad)
175 nax = divider.new_horizontal(size=size, pad=pad)
145 ax.figure.add_axes(nax)
176 ax.figure.add_axes(nax)
146 return nax
177 return nax
147
178
148 self.setup()
179 self.setup()
149
180
150 def setup(self):
181 def setup(self):
151 '''
182 '''
152 This method should be implemented in the child class, the following
183 This method should be implemented in the child class, the following
153 attributes should be set:
184 attributes should be set:
154
185
155 self.nrows: number of rows
186 self.nrows: number of rows
156 self.ncols: number of cols
187 self.ncols: number of cols
157 self.nplots: number of plots (channels or pairs)
188 self.nplots: number of plots (channels or pairs)
158 self.ylabel: label for Y axes
189 self.ylabel: label for Y axes
159 self.titles: list of axes title
190 self.titles: list of axes title
160
191
161 '''
192 '''
162 raise(NotImplementedError, 'Implement this method in child class')
193 raise(NotImplementedError, 'Implement this method in child class')
163
194
164 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
195 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
165 '''
196 '''
166 Create a masked array for missing data
197 Create a masked array for missing data
167 '''
198 '''
168 if x_buffer.shape[0] < 2:
199 if x_buffer.shape[0] < 2:
169 return x_buffer, y_buffer, z_buffer
200 return x_buffer, y_buffer, z_buffer
170
201
171 deltas = x_buffer[1:] - x_buffer[0:-1]
202 deltas = x_buffer[1:] - x_buffer[0:-1]
172 x_median = numpy.median(deltas)
203 x_median = numpy.median(deltas)
173
204
174 index = numpy.where(deltas > 5*x_median)
205 index = numpy.where(deltas > 5*x_median)
175
206
176 if len(index[0]) != 0:
207 if len(index[0]) != 0:
177 z_buffer[::, index[0], ::] = self.__missing
208 z_buffer[::, index[0], ::] = self.__missing
178 z_buffer = numpy.ma.masked_inside(z_buffer,
209 z_buffer = numpy.ma.masked_inside(z_buffer,
179 0.99*self.__missing,
210 0.99*self.__missing,
180 1.01*self.__missing)
211 1.01*self.__missing)
181
212
182 return x_buffer, y_buffer, z_buffer
213 return x_buffer, y_buffer, z_buffer
183
214
184 def decimate(self):
215 def decimate(self):
185
216
186 # dx = int(len(self.x)/self.__MAXNUMX) + 1
217 # dx = int(len(self.x)/self.__MAXNUMX) + 1
187 dy = int(len(self.y)/self.__MAXNUMY) + 1
218 dy = int(len(self.y)/self.__MAXNUMY) + 1
188
219
189 # x = self.x[::dx]
220 # x = self.x[::dx]
190 x = self.x
221 x = self.x
191 y = self.y[::dy]
222 y = self.y[::dy]
192 z = self.z[::, ::, ::dy]
223 z = self.z[::, ::, ::dy]
193
224
194 return x, y, z
225 return x, y, z
195
226
196 def format(self):
227 def format(self):
197 '''
228 '''
198 Set min and max values, labels, ticks and titles
229 Set min and max values, labels, ticks and titles
199 '''
230 '''
200
231
201 if self.xmin is None:
232 if self.xmin is None:
202 xmin = self.min_time
233 xmin = self.min_time
203 else:
234 else:
204 if self.xaxis is 'time':
235 if self.xaxis is 'time':
205 dt = datetime.datetime.fromtimestamp(self.min_time)
236 dt = datetime.datetime.fromtimestamp(self.min_time)
206 xmin = (datetime.datetime.combine(dt.date(),
237 xmin = (datetime.datetime.combine(dt.date(),
207 datetime.time(int(self.xmin), 0, 0))-d1970).total_seconds()
238 datetime.time(int(self.xmin), 0, 0))-UT1970).total_seconds()
208 else:
239 else:
209 xmin = self.xmin
240 xmin = self.xmin
210
241
211 if self.xmax is None:
242 if self.xmax is None:
212 xmax = xmin+self.xrange*60*60
243 xmax = xmin+self.xrange*60*60
213 else:
244 else:
214 if self.xaxis is 'time':
245 if self.xaxis is 'time':
215 dt = datetime.datetime.fromtimestamp(self.min_time)
246 dt = datetime.datetime.fromtimestamp(self.min_time)
216 xmax = (datetime.datetime.combine(dt.date(),
247 xmax = (datetime.datetime.combine(dt.date(),
217 datetime.time(int(self.xmax), 0, 0))-d1970).total_seconds()
248 datetime.time(int(self.xmax), 0, 0))-UT1970).total_seconds()
218 else:
249 else:
219 xmax = self.xmax
250 xmax = self.xmax
220
251
221 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
252 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
222 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
253 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
223
254
224 ystep = 200 if ymax>= 800 else 100 if ymax>=400 else 50 if ymax>=200 else 20
255 ystep = 200 if ymax>= 800 else 100 if ymax>=400 else 50 if ymax>=200 else 20
225
256
226 for n, ax in enumerate(self.axes):
257 for n, ax in enumerate(self.axes):
227 if ax.firsttime:
258 if ax.firsttime:
228 ax.set_facecolor(self.bgcolor)
259 ax.set_facecolor(self.bgcolor)
229 ax.yaxis.set_major_locator(MultipleLocator(ystep))
260 ax.yaxis.set_major_locator(MultipleLocator(ystep))
230 if self.xaxis is 'time':
261 if self.xaxis is 'time':
231 ax.xaxis.set_major_formatter(FuncFormatter(func))
262 ax.xaxis.set_major_formatter(FuncFormatter(func))
232 ax.xaxis.set_major_locator(LinearLocator(9))
263 ax.xaxis.set_major_locator(LinearLocator(9))
233 if self.xlabel is not None:
264 if self.xlabel is not None:
234 ax.set_xlabel(self.xlabel)
265 ax.set_xlabel(self.xlabel)
235 ax.set_ylabel(self.ylabel)
266 ax.set_ylabel(self.ylabel)
236 ax.firsttime = False
267 ax.firsttime = False
237 if self.showprofile:
268 if self.showprofile:
238 self.pf_axes[n].set_ylim(ymin, ymax)
269 self.pf_axes[n].set_ylim(ymin, ymax)
239 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
270 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
240 self.pf_axes[n].set_xlabel('dB')
271 self.pf_axes[n].set_xlabel('dB')
241 self.pf_axes[n].grid(b=True, axis='x')
272 self.pf_axes[n].grid(b=True, axis='x')
242 [tick.set_visible(False) for tick in self.pf_axes[n].get_yticklabels()]
273 [tick.set_visible(False) for tick in self.pf_axes[n].get_yticklabels()]
243 if self.colorbar:
274 if self.colorbar:
244 cb = plt.colorbar(ax.plt, ax=ax, pad=0.02)
275 ax.cbar = plt.colorbar(ax.plt, ax=ax, pad=0.02, aspect=10)
245 cb.ax.tick_params(labelsize=8)
276 ax.cbar.ax.tick_params(labelsize=8)
246 if self.cb_label:
277 if self.cb_label:
247 cb.set_label(self.cb_label, size=8)
278 ax.cbar.set_label(self.cb_label, size=8)
248 elif self.cb_labels:
279 elif self.cb_labels:
249 cb.set_label(self.cb_labels[n], size=8)
280 ax.cbar.set_label(self.cb_labels[n], size=8)
250
281
251 ax.set_title('{} - {} UTC'.format(
282 ax.set_title('{} - {} {}'.format(
252 self.titles[n],
283 self.titles[n],
253 datetime.datetime.fromtimestamp(self.max_time).strftime('%H:%M:%S')),
284 datetime.datetime.fromtimestamp(self.max_time).strftime('%H:%M:%S'),
285 self.time_label),
254 size=8)
286 size=8)
255 ax.set_xlim(xmin, xmax)
287 ax.set_xlim(xmin, xmax)
256 ax.set_ylim(ymin, ymax)
288 ax.set_ylim(ymin, ymax)
257
289
258
259 def __plot(self):
290 def __plot(self):
260 '''
291 '''
261 '''
292 '''
262 log.success('Plotting', self.name)
293 log.success('Plotting', self.name)
263
294
264 self.plot()
295 self.plot()
265 self.format()
296 self.format()
266
297
267 for n, fig in enumerate(self.figures):
298 for n, fig in enumerate(self.figures):
268 if self.nrows == 0 or self.nplots == 0:
299 if self.nrows == 0 or self.nplots == 0:
269 log.warning('No data', self.name)
300 log.warning('No data', self.name)
270 continue
301 continue
271 if self.show:
302 if self.show:
272 fig.show()
303 fig.show()
273
304
274 fig.tight_layout()
305 fig.tight_layout()
275 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
306 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
276 datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d')))
307 datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d')))
277 # fig.canvas.draw()
308 # fig.canvas.draw()
278
309
279 if self.save and self.data.ended:
310 if self.save and self.data.ended:
280 channels = range(self.nrows)
311 channels = range(self.nrows)
281 if self.oneFigure:
312 if self.oneFigure:
282 label = ''
313 label = ''
283 else:
314 else:
284 label = '_{}'.format(channels[n])
315 label = '_{}'.format(channels[n])
285 figname = os.path.join(
316 figname = os.path.join(
286 self.save,
317 self.save,
287 '{}{}_{}.png'.format(
318 '{}{}_{}.png'.format(
288 self.CODE,
319 self.CODE,
289 label,
320 label,
290 datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')
321 datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')
291 )
322 )
292 )
323 )
293 print 'Saving figure: {}'.format(figname)
324 print 'Saving figure: {}'.format(figname)
294 fig.savefig(figname)
325 fig.savefig(figname)
295
326
296 def plot(self):
327 def plot(self):
297 '''
328 '''
298 '''
329 '''
299 raise(NotImplementedError, 'Implement this method in child class')
330 raise(NotImplementedError, 'Implement this method in child class')
300
331
301 def run(self):
332 def run(self):
302
333
303 log.success('Starting', self.name)
334 log.success('Starting', self.name)
304
335
305 context = zmq.Context()
336 context = zmq.Context()
306 receiver = context.socket(zmq.SUB)
337 receiver = context.socket(zmq.SUB)
307 receiver.setsockopt(zmq.SUBSCRIBE, '')
338 receiver.setsockopt(zmq.SUBSCRIBE, '')
308 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
339 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
309
340
310 if 'server' in self.kwargs['parent']:
341 if 'server' in self.kwargs['parent']:
311 receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
342 receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
312 else:
343 else:
313 receiver.connect("ipc:///tmp/zmq.plots")
344 receiver.connect("ipc:///tmp/zmq.plots")
314
345
315 while True:
346 while True:
316 try:
347 try:
317 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
348 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
318
349
319 self.min_time = self.data.times[0]
350 if self.localtime:
320 self.max_time = self.data.times[-1]
351 self.times = self.data.times - time.timezone
352 else:
353 self.times = self.data.times
354
355 self.min_time = self.times[0]
356 self.max_time = self.times[-1]
321
357
322 if self.isConfig is False:
358 if self.isConfig is False:
323 self.__setup()
359 self.__setup()
324 self.isConfig = True
360 self.isConfig = True
325
361
326 self.__plot()
362 self.__plot()
327
363
328 except zmq.Again as e:
364 except zmq.Again as e:
329 log.log('Waiting for data...')
365 log.log('Waiting for data...')
330 if self.data:
366 if self.data:
331 plt.pause(self.data.throttle)
367 plt.pause(self.data.throttle)
332 else:
368 else:
333 time.sleep(2)
369 time.sleep(2)
334
370
335 def close(self):
371 def close(self):
336 if self.data:
372 if self.data:
337 self.__plot()
373 self.__plot()
338
374
339 class PlotSpectraData(PlotData):
375 class PlotSpectraData(PlotData):
340 '''
376 '''
341 Plot for Spectra data
377 Plot for Spectra data
342 '''
378 '''
343
379
344 CODE = 'spc'
380 CODE = 'spc'
345 colormap = 'jro'
381 colormap = 'jro'
346
382
347 def setup(self):
383 def setup(self):
348 self.nplots = len(self.data.channels)
384 self.nplots = len(self.data.channels)
349 self.ncols = int(numpy.sqrt(self.nplots)+ 0.9)
385 self.ncols = int(numpy.sqrt(self.nplots)+ 0.9)
350 self.nrows = int((1.0*self.nplots/self.ncols) + 0.9)
386 self.nrows = int((1.0*self.nplots/self.ncols) + 0.9)
351 self.width = 3.4*self.ncols
387 self.width = 3.4*self.ncols
352 self.height = 3*self.nrows
388 self.height = 3*self.nrows
353 self.cb_label = 'dB'
389 self.cb_label = 'dB'
354 if self.showprofile:
390 if self.showprofile:
355 self.width += 0.8*self.ncols
391 self.width += 0.8*self.ncols
356
392
357 self.ylabel = 'Range [Km]'
393 self.ylabel = 'Range [Km]'
358
394
359 def plot(self):
395 def plot(self):
360 if self.xaxis == "frequency":
396 if self.xaxis == "frequency":
361 x = self.data.xrange[0]
397 x = self.data.xrange[0]
362 self.xlabel = "Frequency (kHz)"
398 self.xlabel = "Frequency (kHz)"
363 elif self.xaxis == "time":
399 elif self.xaxis == "time":
364 x = self.data.xrange[1]
400 x = self.data.xrange[1]
365 self.xlabel = "Time (ms)"
401 self.xlabel = "Time (ms)"
366 else:
402 else:
367 x = self.data.xrange[2]
403 x = self.data.xrange[2]
368 self.xlabel = "Velocity (m/s)"
404 self.xlabel = "Velocity (m/s)"
369
405
370 if self.CODE == 'spc_mean':
406 if self.CODE == 'spc_mean':
371 x = self.data.xrange[2]
407 x = self.data.xrange[2]
372 self.xlabel = "Velocity (m/s)"
408 self.xlabel = "Velocity (m/s)"
373
409
374 self.titles = []
410 self.titles = []
375
411
376 y = self.data.heights
412 y = self.data.heights
377 self.y = y
413 self.y = y
378 z = self.data['spc']
414 z = self.data['spc']
379
415
380 for n, ax in enumerate(self.axes):
416 for n, ax in enumerate(self.axes):
381 noise = self.data['noise'][n][-1]
417 noise = self.data['noise'][n][-1]
382 if self.CODE == 'spc_mean':
418 if self.CODE == 'spc_mean':
383 mean = self.data['mean'][n][-1]
419 mean = self.data['mean'][n][-1]
384 if ax.firsttime:
420 if ax.firsttime:
385 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
421 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
386 self.xmin = self.xmin if self.xmin else -self.xmax
422 self.xmin = self.xmin if self.xmin else -self.xmax
387 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
423 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
388 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
424 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
389 ax.plt = ax.pcolormesh(x, y, z[n].T,
425 ax.plt = ax.pcolormesh(x, y, z[n].T,
390 vmin=self.zmin,
426 vmin=self.zmin,
391 vmax=self.zmax,
427 vmax=self.zmax,
392 cmap=plt.get_cmap(self.colormap)
428 cmap=plt.get_cmap(self.colormap)
393 )
429 )
394
430
395 if self.showprofile:
431 if self.showprofile:
396 ax.plt_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], y)[0]
432 ax.plt_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], y)[0]
397 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
433 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
398 color="k", linestyle="dashed", lw=1)[0]
434 color="k", linestyle="dashed", lw=1)[0]
399 if self.CODE == 'spc_mean':
435 if self.CODE == 'spc_mean':
400 ax.plt_mean = ax.plot(mean, y, color='k')[0]
436 ax.plt_mean = ax.plot(mean, y, color='k')[0]
401 else:
437 else:
402 ax.plt.set_array(z[n].T.ravel())
438 ax.plt.set_array(z[n].T.ravel())
403 if self.showprofile:
439 if self.showprofile:
404 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
440 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
405 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
441 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
406 if self.CODE == 'spc_mean':
442 if self.CODE == 'spc_mean':
407 ax.plt_mean.set_data(mean, y)
443 ax.plt_mean.set_data(mean, y)
408
444
409 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
445 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
410 self.saveTime = self.max_time
446 self.saveTime = self.max_time
411
447
412
448
413 class PlotCrossSpectraData(PlotData):
449 class PlotCrossSpectraData(PlotData):
414
450
415 CODE = 'cspc'
451 CODE = 'cspc'
416 zmin_coh = None
452 zmin_coh = None
417 zmax_coh = None
453 zmax_coh = None
418 zmin_phase = None
454 zmin_phase = None
419 zmax_phase = None
455 zmax_phase = None
420
456
421 def setup(self):
457 def setup(self):
422
458
423 self.ncols = 4
459 self.ncols = 4
424 self.nrows = len(self.data.pairs)
460 self.nrows = len(self.data.pairs)
425 self.nplots = self.nrows*4
461 self.nplots = self.nrows*4
426 self.width = 3.4*self.ncols
462 self.width = 3.4*self.ncols
427 self.height = 3*self.nrows
463 self.height = 3*self.nrows
428 self.ylabel = 'Range [Km]'
464 self.ylabel = 'Range [Km]'
429 self.showprofile = False
465 self.showprofile = False
430
466
431 def plot(self):
467 def plot(self):
432
468
433 if self.xaxis == "frequency":
469 if self.xaxis == "frequency":
434 x = self.data.xrange[0]
470 x = self.data.xrange[0]
435 self.xlabel = "Frequency (kHz)"
471 self.xlabel = "Frequency (kHz)"
436 elif self.xaxis == "time":
472 elif self.xaxis == "time":
437 x = self.data.xrange[1]
473 x = self.data.xrange[1]
438 self.xlabel = "Time (ms)"
474 self.xlabel = "Time (ms)"
439 else:
475 else:
440 x = self.data.xrange[2]
476 x = self.data.xrange[2]
441 self.xlabel = "Velocity (m/s)"
477 self.xlabel = "Velocity (m/s)"
442
478
443 self.titles = []
479 self.titles = []
444
480
445 y = self.data.heights
481 y = self.data.heights
446 self.y = y
482 self.y = y
447 spc = self.data['spc']
483 spc = self.data['spc']
448 cspc = self.data['cspc']
484 cspc = self.data['cspc']
449
485
450 for n in range(self.nrows):
486 for n in range(self.nrows):
451 noise = self.data['noise'][n][-1]
487 noise = self.data['noise'][n][-1]
452 pair = self.data.pairs[n]
488 pair = self.data.pairs[n]
453 ax = self.axes[4*n]
489 ax = self.axes[4*n]
454 ax3 = self.axes[4*n+3]
490 ax3 = self.axes[4*n+3]
455 if ax.firsttime:
491 if ax.firsttime:
456 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
492 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
457 self.xmin = self.xmin if self.xmin else -self.xmax
493 self.xmin = self.xmin if self.xmin else -self.xmax
458 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
494 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
459 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
495 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
460 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
496 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
461 vmin=self.zmin,
497 vmin=self.zmin,
462 vmax=self.zmax,
498 vmax=self.zmax,
463 cmap=plt.get_cmap(self.colormap)
499 cmap=plt.get_cmap(self.colormap)
464 )
500 )
465 else:
501 else:
466 ax.plt.set_array(spc[pair[0]].T.ravel())
502 ax.plt.set_array(spc[pair[0]].T.ravel())
467 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
503 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
468
504
469 ax = self.axes[4*n+1]
505 ax = self.axes[4*n+1]
470 if ax.firsttime:
506 if ax.firsttime:
471 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
507 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
472 vmin=self.zmin,
508 vmin=self.zmin,
473 vmax=self.zmax,
509 vmax=self.zmax,
474 cmap=plt.get_cmap(self.colormap)
510 cmap=plt.get_cmap(self.colormap)
475 )
511 )
476 else:
512 else:
477 ax.plt.set_array(spc[pair[1]].T.ravel())
513 ax.plt.set_array(spc[pair[1]].T.ravel())
478 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
514 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
479
515
480 out = cspc[n]/numpy.sqrt(spc[pair[0]]*spc[pair[1]])
516 out = cspc[n]/numpy.sqrt(spc[pair[0]]*spc[pair[1]])
481 coh = numpy.abs(out)
517 coh = numpy.abs(out)
482 phase = numpy.arctan2(out.imag, out.real)*180/numpy.pi
518 phase = numpy.arctan2(out.imag, out.real)*180/numpy.pi
483
519
484 ax = self.axes[4*n+2]
520 ax = self.axes[4*n+2]
485 if ax.firsttime:
521 if ax.firsttime:
486 ax.plt = ax.pcolormesh(x, y, coh.T,
522 ax.plt = ax.pcolormesh(x, y, coh.T,
487 vmin=0,
523 vmin=0,
488 vmax=1,
524 vmax=1,
489 cmap=plt.get_cmap(self.colormap_coh)
525 cmap=plt.get_cmap(self.colormap_coh)
490 )
526 )
491 else:
527 else:
492 ax.plt.set_array(coh.T.ravel())
528 ax.plt.set_array(coh.T.ravel())
493 self.titles.append('Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
529 self.titles.append('Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
494
530
495 ax = self.axes[4*n+3]
531 ax = self.axes[4*n+3]
496 if ax.firsttime:
532 if ax.firsttime:
497 ax.plt = ax.pcolormesh(x, y, phase.T,
533 ax.plt = ax.pcolormesh(x, y, phase.T,
498 vmin=-180,
534 vmin=-180,
499 vmax=180,
535 vmax=180,
500 cmap=plt.get_cmap(self.colormap_phase)
536 cmap=plt.get_cmap(self.colormap_phase)
501 )
537 )
502 else:
538 else:
503 ax.plt.set_array(phase.T.ravel())
539 ax.plt.set_array(phase.T.ravel())
504 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
540 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
505
541
506 self.saveTime = self.max_time
542 self.saveTime = self.max_time
507
543
508
544
509 class PlotSpectraMeanData(PlotSpectraData):
545 class PlotSpectraMeanData(PlotSpectraData):
510 '''
546 '''
511 Plot for Spectra and Mean
547 Plot for Spectra and Mean
512 '''
548 '''
513 CODE = 'spc_mean'
549 CODE = 'spc_mean'
514 colormap = 'jro'
550 colormap = 'jro'
515
551
516
552
517 class PlotRTIData(PlotData):
553 class PlotRTIData(PlotData):
518 '''
554 '''
519 Plot for RTI data
555 Plot for RTI data
520 '''
556 '''
521
557
522 CODE = 'rti'
558 CODE = 'rti'
523 colormap = 'jro'
559 colormap = 'jro'
524
560
525 def setup(self):
561 def setup(self):
526 self.xaxis = 'time'
562 self.xaxis = 'time'
527 self.ncols = 1
563 self.ncols = 1
528 self.nrows = len(self.data.channels)
564 self.nrows = len(self.data.channels)
529 self.nplots = len(self.data.channels)
565 self.nplots = len(self.data.channels)
530 self.ylabel = 'Range [Km]'
566 self.ylabel = 'Range [Km]'
531 self.cb_label = 'dB'
567 self.cb_label = 'dB'
532 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
568 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
533
569
534 def plot(self):
570 def plot(self):
535 self.x = self.data.times
571 self.x = self.times
536 self.y = self.data.heights
572 self.y = self.data.heights
537 self.z = self.data[self.CODE]
573 self.z = self.data[self.CODE]
538 self.z = numpy.ma.masked_invalid(self.z)
574 self.z = numpy.ma.masked_invalid(self.z)
539
575
540 for n, ax in enumerate(self.axes):
576 for n, ax in enumerate(self.axes):
541 x, y, z = self.fill_gaps(*self.decimate())
577 x, y, z = self.fill_gaps(*self.decimate())
542 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
578 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
543 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
579 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
544 if ax.firsttime:
580 if ax.firsttime:
545 ax.plt = ax.pcolormesh(x, y, z[n].T,
581 ax.plt = ax.pcolormesh(x, y, z[n].T,
546 vmin=self.zmin,
582 vmin=self.zmin,
547 vmax=self.zmax,
583 vmax=self.zmax,
548 cmap=plt.get_cmap(self.colormap)
584 cmap=plt.get_cmap(self.colormap)
549 )
585 )
550 if self.showprofile:
586 if self.showprofile:
551 ax.plot_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], self.y)[0]
587 ax.plot_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], self.y)[0]
552 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
588 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
553 color="k", linestyle="dashed", lw=1)[0]
589 color="k", linestyle="dashed", lw=1)[0]
554 else:
590 else:
555 ax.collections.remove(ax.collections[0])
591 ax.collections.remove(ax.collections[0])
556 ax.plt = ax.pcolormesh(x, y, z[n].T,
592 ax.plt = ax.pcolormesh(x, y, z[n].T,
557 vmin=self.zmin,
593 vmin=self.zmin,
558 vmax=self.zmax,
594 vmax=self.zmax,
559 cmap=plt.get_cmap(self.colormap)
595 cmap=plt.get_cmap(self.colormap)
560 )
596 )
561 if self.showprofile:
597 if self.showprofile:
562 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
598 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
563 ax.plot_noise.set_data(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y)
599 ax.plot_noise.set_data(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y)
564
600
565 self.saveTime = self.min_time
601 self.saveTime = self.min_time
566
602
567
603
568 class PlotCOHData(PlotRTIData):
604 class PlotCOHData(PlotRTIData):
569 '''
605 '''
570 Plot for Coherence data
606 Plot for Coherence data
571 '''
607 '''
572
608
573 CODE = 'coh'
609 CODE = 'coh'
574
610
575 def setup(self):
611 def setup(self):
576 self.xaxis = 'time'
612 self.xaxis = 'time'
577 self.ncols = 1
613 self.ncols = 1
578 self.nrows = len(self.data.pairs)
614 self.nrows = len(self.data.pairs)
579 self.nplots = len(self.data.pairs)
615 self.nplots = len(self.data.pairs)
580 self.ylabel = 'Range [Km]'
616 self.ylabel = 'Range [Km]'
581 if self.CODE == 'coh':
617 if self.CODE == 'coh':
582 self.cb_label = ''
618 self.cb_label = ''
583 self.titles = ['Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
619 self.titles = ['Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
584 else:
620 else:
585 self.cb_label = 'Degrees'
621 self.cb_label = 'Degrees'
586 self.titles = ['Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
622 self.titles = ['Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
587
623
588
624
589 class PlotPHASEData(PlotCOHData):
625 class PlotPHASEData(PlotCOHData):
590 '''
626 '''
591 Plot for Phase map data
627 Plot for Phase map data
592 '''
628 '''
593
629
594 CODE = 'phase'
630 CODE = 'phase'
595 colormap = 'seismic'
631 colormap = 'seismic'
596
632
597
633
598 class PlotNoiseData(PlotData):
634 class PlotNoiseData(PlotData):
599 '''
635 '''
600 Plot for noise
636 Plot for noise
601 '''
637 '''
602
638
603 CODE = 'noise'
639 CODE = 'noise'
604
640
605 def setup(self):
641 def setup(self):
606 self.xaxis = 'time'
642 self.xaxis = 'time'
607 self.ncols = 1
643 self.ncols = 1
608 self.nrows = 1
644 self.nrows = 1
609 self.nplots = 1
645 self.nplots = 1
610 self.ylabel = 'Intensity [dB]'
646 self.ylabel = 'Intensity [dB]'
611 self.titles = ['Noise']
647 self.titles = ['Noise']
612 self.colorbar = False
648 self.colorbar = False
613
649
614 def plot(self):
650 def plot(self):
615
651
616 x = self.data.times
652 x = self.times
617 xmin = self.min_time
653 xmin = self.min_time
618 xmax = xmin+self.xrange*60*60
654 xmax = xmin+self.xrange*60*60
619 Y = self.data[self.CODE]
655 Y = self.data[self.CODE]
620
656
621 if self.axes[0].firsttime:
657 if self.axes[0].firsttime:
622 for ch in self.data.channels:
658 for ch in self.data.channels:
623 y = Y[ch]
659 y = Y[ch]
624 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
660 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
625 plt.legend()
661 plt.legend()
626 else:
662 else:
627 for ch in self.data.channels:
663 for ch in self.data.channels:
628 y = Y[ch]
664 y = Y[ch]
629 self.axes[0].lines[ch].set_data(x, y)
665 self.axes[0].lines[ch].set_data(x, y)
630
666
631 self.ymin = numpy.nanmin(Y) - 5
667 self.ymin = numpy.nanmin(Y) - 5
632 self.ymax = numpy.nanmax(Y) + 5
668 self.ymax = numpy.nanmax(Y) + 5
633 self.saveTime = self.min_time
669 self.saveTime = self.min_time
634
670
635
671
636 class PlotSNRData(PlotRTIData):
672 class PlotSNRData(PlotRTIData):
637 '''
673 '''
638 Plot for SNR Data
674 Plot for SNR Data
639 '''
675 '''
640
676
641 CODE = 'snr'
677 CODE = 'snr'
642 colormap = 'jet'
678 colormap = 'jet'
643
679
644
680
645 class PlotDOPData(PlotRTIData):
681 class PlotDOPData(PlotRTIData):
646 '''
682 '''
647 Plot for DOPPLER Data
683 Plot for DOPPLER Data
648 '''
684 '''
649
685
650 CODE = 'dop'
686 CODE = 'dop'
651 colormap = 'jet'
687 colormap = 'jet'
652
688
653
689
654 class PlotSkyMapData(PlotData):
690 class PlotSkyMapData(PlotData):
655 '''
691 '''
656 Plot for meteors detection data
692 Plot for meteors detection data
657 '''
693 '''
658
694
659 CODE = 'met'
695 CODE = 'met'
660
696
661 def setup(self):
697 def setup(self):
662
698
663 self.ncols = 1
699 self.ncols = 1
664 self.nrows = 1
700 self.nrows = 1
665 self.width = 7.2
701 self.width = 7.2
666 self.height = 7.2
702 self.height = 7.2
667
703
668 self.xlabel = 'Zonal Zenith Angle (deg)'
704 self.xlabel = 'Zonal Zenith Angle (deg)'
669 self.ylabel = 'Meridional Zenith Angle (deg)'
705 self.ylabel = 'Meridional Zenith Angle (deg)'
670
706
671 if self.figure is None:
707 if self.figure is None:
672 self.figure = plt.figure(figsize=(self.width, self.height),
708 self.figure = plt.figure(figsize=(self.width, self.height),
673 edgecolor='k',
709 edgecolor='k',
674 facecolor='w')
710 facecolor='w')
675 else:
711 else:
676 self.figure.clf()
712 self.figure.clf()
677
713
678 self.ax = plt.subplot2grid((self.nrows, self.ncols), (0, 0), 1, 1, polar=True)
714 self.ax = plt.subplot2grid((self.nrows, self.ncols), (0, 0), 1, 1, polar=True)
679 self.ax.firsttime = True
715 self.ax.firsttime = True
680
716
681
717
682 def plot(self):
718 def plot(self):
683
719
684 arrayParameters = numpy.concatenate([self.data['param'][t] for t in self.data.times])
720 arrayParameters = numpy.concatenate([self.data['param'][t] for t in self.times])
685 error = arrayParameters[:,-1]
721 error = arrayParameters[:,-1]
686 indValid = numpy.where(error == 0)[0]
722 indValid = numpy.where(error == 0)[0]
687 finalMeteor = arrayParameters[indValid,:]
723 finalMeteor = arrayParameters[indValid,:]
688 finalAzimuth = finalMeteor[:,3]
724 finalAzimuth = finalMeteor[:,3]
689 finalZenith = finalMeteor[:,4]
725 finalZenith = finalMeteor[:,4]
690
726
691 x = finalAzimuth*numpy.pi/180
727 x = finalAzimuth*numpy.pi/180
692 y = finalZenith
728 y = finalZenith
693
729
694 if self.ax.firsttime:
730 if self.ax.firsttime:
695 self.ax.plot = self.ax.plot(x, y, 'bo', markersize=5)[0]
731 self.ax.plot = self.ax.plot(x, y, 'bo', markersize=5)[0]
696 self.ax.set_ylim(0,90)
732 self.ax.set_ylim(0,90)
697 self.ax.set_yticks(numpy.arange(0,90,20))
733 self.ax.set_yticks(numpy.arange(0,90,20))
698 self.ax.set_xlabel(self.xlabel)
734 self.ax.set_xlabel(self.xlabel)
699 self.ax.set_ylabel(self.ylabel)
735 self.ax.set_ylabel(self.ylabel)
700 self.ax.yaxis.labelpad = 40
736 self.ax.yaxis.labelpad = 40
701 self.ax.firsttime = False
737 self.ax.firsttime = False
702 else:
738 else:
703 self.ax.plot.set_data(x, y)
739 self.ax.plot.set_data(x, y)
704
740
705
741
706 dt1 = datetime.datetime.fromtimestamp(self.min_time).strftime('%y/%m/%d %H:%M:%S')
742 dt1 = datetime.datetime.fromtimestamp(self.min_time).strftime('%y/%m/%d %H:%M:%S')
707 dt2 = datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')
743 dt2 = datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')
708 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
744 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
709 dt2,
745 dt2,
710 len(x))
746 len(x))
711 self.ax.set_title(title, size=8)
747 self.ax.set_title(title, size=8)
712
748
713 self.saveTime = self.max_time
749 self.saveTime = self.max_time
714
750
715 class PlotParamData(PlotRTIData):
751 class PlotParamData(PlotRTIData):
716 '''
752 '''
717 Plot for data_param object
753 Plot for data_param object
718 '''
754 '''
719
755
720 CODE = 'param'
756 CODE = 'param'
721 colormap = 'seismic'
757 colormap = 'seismic'
722
758
723 def setup(self):
759 def setup(self):
724 self.xaxis = 'time'
760 self.xaxis = 'time'
725 self.ncols = 1
761 self.ncols = 1
726 self.nrows = self.data.shape(self.CODE)[0]
762 self.nrows = self.data.shape(self.CODE)[0]
727 self.nplots = self.nrows
763 self.nplots = self.nrows
728 if self.showSNR:
764 if self.showSNR:
729 self.nrows += 1
765 self.nrows += 1
730 self.nplots += 1
766 self.nplots += 1
731
767
732 self.ylabel = 'Height [Km]'
768 self.ylabel = 'Height [Km]'
733 self.titles = self.data.parameters \
769 self.titles = self.data.parameters \
734 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
770 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
735 if self.showSNR:
771 if self.showSNR:
736 self.titles.append('SNR')
772 self.titles.append('SNR')
737
773
738 def plot(self):
774 def plot(self):
739 self.data.normalize_heights()
775 self.data.normalize_heights()
740 self.x = self.data.times
776 self.x = self.times
741 self.y = self.data.heights
777 self.y = self.data.heights
742 if self.showSNR:
778 if self.showSNR:
743 self.z = numpy.concatenate(
779 self.z = numpy.concatenate(
744 (self.data[self.CODE], self.data['snr'])
780 (self.data[self.CODE], self.data['snr'])
745 )
781 )
746 else:
782 else:
747 self.z = self.data[self.CODE]
783 self.z = self.data[self.CODE]
748
784
749 self.z = numpy.ma.masked_invalid(self.z)
785 self.z = numpy.ma.masked_invalid(self.z)
750
786
751 for n, ax in enumerate(self.axes):
787 for n, ax in enumerate(self.axes):
752
788
753 x, y, z = self.fill_gaps(*self.decimate())
789 x, y, z = self.fill_gaps(*self.decimate())
754
790
755 if ax.firsttime:
791 if ax.firsttime:
756 if self.zlimits is not None:
792 if self.zlimits is not None:
757 self.zmin, self.zmax = self.zlimits[n]
793 self.zmin, self.zmax = self.zlimits[n]
758 self.zmax = self.zmax if self.zmax is not None else numpy.nanmax(abs(self.z[:-1, :]))
794 self.zmax = self.zmax if self.zmax is not None else numpy.nanmax(abs(self.z[:-1, :]))
759 self.zmin = self.zmin if self.zmin is not None else -self.zmax
795 self.zmin = self.zmin if self.zmin is not None else -self.zmax
760 ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n],
796 ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n],
761 vmin=self.zmin,
797 vmin=self.zmin,
762 vmax=self.zmax,
798 vmax=self.zmax,
763 cmap=self.cmaps[n]
799 cmap=self.cmaps[n]
764 )
800 )
765 else:
801 else:
766 if self.zlimits is not None:
802 if self.zlimits is not None:
767 self.zmin, self.zmax = self.zlimits[n]
803 self.zmin, self.zmax = self.zlimits[n]
768 ax.collections.remove(ax.collections[0])
804 ax.collections.remove(ax.collections[0])
769 ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n],
805 ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n],
770 vmin=self.zmin,
806 vmin=self.zmin,
771 vmax=self.zmax,
807 vmax=self.zmax,
772 cmap=self.cmaps[n]
808 cmap=self.cmaps[n]
773 )
809 )
774
810
775 self.saveTime = self.min_time
811 self.saveTime = self.min_time
776
812
777 class PlotOuputData(PlotParamData):
813 class PlotOuputData(PlotParamData):
778 '''
814 '''
779 Plot data_output object
815 Plot data_output object
780 '''
816 '''
781
817
782 CODE = 'output'
818 CODE = 'output'
783 colormap = 'seismic'
819 colormap = 'seismic'
General Comments 0
You need to be logged in to leave comments. Login now