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