jroplot_data.py
258 lines
| 7.3 KiB
| text/x-python
|
PythonLexer
|
r865 | ||
import os | |||
import time | |||
import numpy | |||
import datetime | |||
import numpy as np | |||
import matplotlib.pyplot as plt | |||
from mpl_toolkits.axes_grid1 import make_axes_locatable | |||
from matplotlib.ticker import FuncFormatter, LinearLocator | |||
from schainpy.model.proc.jroproc_base import Operation | |||
func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime('%H:%M')) | |||
d1970 = datetime.datetime(1970,1,1) | |||
class PlotData(Operation): | |||
|
r866 | __code = 'Figure' | |
|
r865 | __MAXNUMX = 80 | |
__MAXNUMY = 80 | |||
__missing = 1E30 | |||
def __init__(self): | |||
Operation.__init__(self) | |||
self.xmin = None | |||
self.xmax = None | |||
self.newdataOut = None | |||
self.dataOut = None | |||
self.isConfig = False | |||
self.figure = None | |||
|
r866 | self.width = 6 | |
self.height = 4 | |||
|
r865 | ||
def setup(self, dataOut, **kwargs): | |||
self.first = True | |||
self.localtime = kwargs.pop('localtime', True) | |||
self.show = kwargs.pop('show', True) | |||
self.save = kwargs.pop('save', False) | |||
self.pause = kwargs.pop('pause', False) | |||
self.time = [] | |||
self.nblock = 0 | |||
self.z = [] | |||
self.data = [{} for __ in dataOut.channelList] | |||
self.axes = [] | |||
self.colormap = kwargs.get('colormap', 'jet') | |||
|
r866 | self.title = kwargs.get('wintitle', '') | |
|
r865 | self.xaxis = kwargs.get('xaxis', None) | |
self.zmin = kwargs.get('zmin', None) | |||
self.zmax = kwargs.get('zmax', None) | |||
xmin = kwargs.get('xmin', 0) | |||
xmax = kwargs.get('xmax', xmin+4) | |||
dt = dataOut.datatime.date() | |||
dtmin = datetime.datetime.combine(dt, datetime.time(xmin, 0, 0)) | |||
dtmax = datetime.datetime.combine(dt, datetime.time(xmax, 59, 59)) | |||
self.xmin = (dtmin-d1970).total_seconds() | |||
self.xmax = (dtmax-d1970).total_seconds() | |||
|
r866 | self.ymin = kwargs.get('ymin', None) | |
self.ymax = kwargs.get('ymax', None) | |||
|
r865 | ||
if self.figure is None: | |||
self.figure = plt.figure() | |||
else: | |||
self.figure.clf() | |||
|
r866 | self.setup_fig() | |
|
r865 | for n in range(dataOut.nChannels): | |
ax = self.figure.add_subplot(self.nrows, self.ncols, n+1) | |||
ax.firsttime = True | |||
self.axes.append(ax) | |||
|
r866 | self.setup_fig() | |
|
r865 | self.figure.set_size_inches (self.width, self.height) | |
def fill_gaps(self, x_buffer, y_buffer, z_buffer): | |||
if x_buffer.shape[0] < 2: | |||
return x_buffer, y_buffer, z_buffer | |||
deltas = x_buffer[1:] - x_buffer[0:-1] | |||
x_median = np.median(deltas) | |||
index = np.where(deltas > 5*x_median) | |||
if len(index[0]) != 0: | |||
|
r866 | z_buffer[::,index[0],::] = self.__missing | |
|
r865 | z_buffer = np.ma.masked_inside(z_buffer, | |
0.99*self.__missing, | |||
1.01*self.__missing) | |||
return x_buffer, y_buffer, z_buffer | |||
|
r866 | def decimate(self): | |
dx = int(len(self.x)/self.__MAXNUMX) + 1 | |||
dy = int(len(self.y)/self.__MAXNUMY) + 1 | |||
x = self.x[::dx] | |||
y = self.y[::dy] | |||
z = self.z[::, ::dx, ::dy] | |||
return x, y, z | |||
def _plot(self): | |||
self.plot() | |||
self.figure.suptitle(self.title+self.__code) | |||
if self.save: | |||
figname = os.path.join(self.save, '{}_{}.png'.format(self.__code, | |||
self.plot_dt.strftime('%y%m%d_%H%M%S'))) | |||
print 'Saving figure: {}'.format(figname) | |||
self.figure.savefig(figname) | |||
self.figure.canvas.draw() | |||
if self.show: | |||
self.figure.show() | |||
if self.pause: | |||
raw_input('Press <ENTER> to continue') | |||
def update(self): | |||
pass | |||
def run(self, dataOut, **kwargs): | |||
self.dataOut = dataOut | |||
if not self.isConfig: | |||
self.setup(dataOut, **kwargs) | |||
self.isConfig = True | |||
self.nblock += 1 | |||
self.update() | |||
if dataOut.ltctime>=self.xmax: | |||
self._plot() | |||
self.isConfig = False | |||
def close(self): | |||
if self.dataOut: | |||
self._plot() | |||
class PlotSpectraData(PlotData): | |||
__code = 'Spectra' | |||
def setup_fig(self): | |||
pass | |||
def update(self): | |||
for ch in self.dataOut.channelList: | |||
self.data[ch] = self.dataOut.data_spc[ch] | |||
|
r865 | def plot(self): | |
|
r866 | pass | |
class PlotRTIData(PlotData): | |||
__code = 'RTI' | |||
def setup_fig(self): | |||
self.ncols = 1 | |||
self.nrows = self.dataOut.nChannels | |||
self.width = 8 | |||
self.height = 2.2*self.nrows | |||
self.ylabel = 'Range [Km]' | |||
def update(self): | |||
self.time.append(self.dataOut.ltctime) | |||
for ch in self.dataOut.channelList: | |||
self.data[ch][self.dataOut.ltctime] = self.dataOut.getPower()[ch] | |||
def plot(self): | |||
self.plot_dt = datetime.datetime.utcfromtimestamp(self.time[-2]) | |||
|
r865 | ||
|
r866 | self.time.sort() | |
self.x = self.time | |||
self.y = self.dataOut.getHeiRange() | |||
self.z = [] | |||
|
r865 | ||
|
r866 | for ch in self.dataOut.channelList: | |
self.z.append([self.data[ch][t] for t in self.time]) | |||
self.x = np.array(self.x) | |||
self.z = np.array(self.z) | |||
|
r865 | ||
for n, ax in enumerate(self.axes): | |||
if self.xaxis=='time': | |||
ax.xaxis.set_major_formatter(FuncFormatter(func)) | |||
ax.xaxis.set_major_locator(LinearLocator(6)) | |||
ax.yaxis.set_major_locator(LinearLocator(4)) | |||
ax.set_ylabel(self.ylabel) | |||
|
r866 | ||
|
r865 | ax.set_xlim(self.xmin, self.xmax) | |
|
r866 | ax.set_title('Channel {} {}'.format(self.dataOut.channelList[n], | |
self.plot_dt.strftime('%y/%m/%d %H:%M:%S')), | |||
size=8) | |||
|
r865 | ||
|
r866 | self.decimate() | |
|
r865 | ||
for n, ax in enumerate(self.axes): | |||
|
r866 | ||
x, y, z = self.fill_gaps(*self.decimate()) | |||
|
r865 | if ax.firsttime: | |
|
r866 | ymin = self.ymin if self.ymin else np.nanmin(self.y) | |
ymax = self.ymax if self.ymax else np.nanmax(self.y) | |||
|
r865 | zmin = self.zmin if self.zmin else np.nanmin(self.z) | |
zmax = self.zmax if self.zmax else np.nanmax(self.z) | |||
|
r866 | plot = ax.pcolormesh(x, y, z[n].T, | |
|
r865 | vmin=zmin, | |
vmax=zmax, | |||
cmap=plt.get_cmap(self.colormap) | |||
) | |||
divider = make_axes_locatable(ax) | |||
cax = divider.new_horizontal(size='3%', pad=0.05) | |||
self.figure.add_axes(cax) | |||
plt.colorbar(plot, cax) | |||
|
r866 | ax.set_ylim(self.ymin, self.ymax) | |
|
r865 | ax.firsttime = False | |
else: | |||
|
r866 | plot = ax.pcolormesh(x, y, z[n].T) | |
|
r865 | ||
self.figure.subplots_adjust(wspace=None, hspace=0.5) | |||
|
r866 | ||
|
r865 | ||
|
r866 | class PlotSNRData(PlotRTIData): | |
__code = 'SNR' | |||
|
r865 | def update(self): | |
|
r866 | ||
|
r865 | self.time.append(self.dataOut.ltctime) | |
|
r866 | for ch in self.dataOut.channelList: | |
self.data[ch][self.dataOut.ltctime] = 10*np.log10(self.dataOut.data_SNR[ch]) |