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