Source code for hydrac.util.display

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Display Hydroacoustic data (:mod:`hydrac.util.display`)
=======================================================

.. autoclass:: Display
   :members:
   :private-members:

"""

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import cm


[docs]class Display(object): """Display class This class is made to automatically display data based on their dimensions given the common data types used in hydrac (Hydroacoustic data, physical parameter data) usin the library matplotlib. With this class, it is possible to display rapidly: - Regular plots using the method :func:`regularplot` - Image plots using the method :func:`imagesplot` All the generated figures are stored in the param modified dictionnary associated to each instrumlent object instance. This class is called by the class :class:`hydrac.instruments.instruments.Instrument` and its method :func:`hydrac.instruments.instruments.Instrument.display_data`. """ def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs if 'plt_type' not in kwargs.keys(): self.kwargs.update({'plt_type': [input('please enter a plot type : ')] * int(len(args) / 2)}) if 'subplot' in self.kwargs.keys(): self.fig, self.axes = plt.subplots(self.kwargs['subplot'][0], self.kwargs['subplot'][1]) self.subplot_set = tuple(self.kwargs['subplot']) del self.kwargs['subplot'] else: self.subplot_set = (1, 1) self.fig, self.axes = plt.subplots(1, 1) self.plt_type = self.kwargs['plt_type'] if len(args) < 1: raise TypeError('Wrong number of arguments') any_in = lambda a, b: bool(set(a).intersection(b)) if any_in(self.plt_type, ['imshow', 'contour', 'contourf', 'pcolor']) == False: if len(args) == 1: if len(np.shape(args[0])) == 1: self.args = [np.arange(len(args[0])), args[0]] self.regularplot() elif len(np.shape(args[0])) > 1: self.args = [np.tile(np.arange(len(args[0])), (np.size(args[0], 1), 1)).T, args[0]] self.regularplot() elif len(args) > 1: if len(args) / 2 == np.floor(len(args) / 2): if np.prod(self.subplot_set) > 1: self.regularplot() else: tot_size = int(len(self.args) / 2) args_tmp = [] for u in range(0, tot_size, 2): if len(np.shape(args[u])) <\ len(np.shape(args[u+1])): args_tmp.append([np.tile(args[u], (np.size(args[1], 1), 1)).T]) args_tmp.append(args[u+1]) else: args_tmp.append(args[u]) args_tmp.append(args[u+1]) self.args = args_tmp self.regularplot() else: if len(args) == 3 * np.prod(self.subplot_set): if len(args) == 3: self.x = args[0] self.y = args[1] self.args = [args[2]] elif len(args) > 3: self.x = [] self.y = [] _del = [] for u in range(0, np.prod(self.subplot_set)): self.x.append(args[3 * u]) self.y.append(args[3 * u+1]) _del.append(3 * u+2) _tmp = [] [_tmp.append(args[t]) for t in _del] self.args = _tmp elif len(args) == np.prod(self.subplot_set): if len(args) == 1: self.x = np.arange(np.size(args[0], 0)) self.y = np.arange(np.size(args[0], 1)) elif len(args) > 1: self.x = [] self.y = [] for u in range(0, np.prod(self.subplot_set)): self.x.append(np.arange(np.size(args[u], 0))) self.y.append(np.arange(np.size(args[u], 1))) print('len(args) & prod = {} et {}'.format(len(args), np.prod(self.subplot_set ))) self.imagesplot() if 'cmap' in self.kwargs.keys() and 'contourf' in self.plt_type: u = [] [u.append(r) for r in enumerate(self.plt_type) if r[1] == 'contourf'] _ind = [ui for ui, iu in u] camp_list = self.kwargs['cmap'] for k in _ind: exec('self.line' + str(k) + '.set_cmap(camp_list[' + str(k) + '])') try: for l in range(0, len(self.plt_type)): exec('self.fig.colorbar(self.line' + str(l) + ',ax=self.axes[' + str(l) + '])') except(TypeError): self.fig.colorbar(self.line0) def update(self, *args): self.args = args self.regularplot() def regularplot(self): try: len(self.axes) print('toto') test1 = np.arange(np.size(self.axes)) test2 = np.reshape(test1, np.shape(self.axes)) for u in range(0, len(self.plt_type)): self.curraxe = u idx_ = np.where(test2 == u) idx_0 = list(idx_[0])[0] if len(idx_) > 1: idx_1 = list(idx_[1])[0] exec('self.line' + str(u) + '=self.axes[idx_0,idx_1].' + self.plt_type[u] + '(np.squeeze(self.args[2*u]), ' + 'np.squeeze(self.args[2*u+1]))') plt.axis([np.min(np.squeeze(self.args[2*u])), np.max(np.squeeze(self.args[2*u])), np.min(np.squeeze(self.args[2*u+1])), np.max(np.squeeze(self.args[2*u+1]))]) self.curraxis = self.axes[idx_0, idx_1] exec('self.rendering_plt(self.line' + str(u) + ')') else: exec('self.line' + str(u) + '=self.axes[idx_0].' + self.plt_type[u] + '(np.squeeze(self.args[2*u]), ' + 'np.squeeze(self.args[2*u+1]))') plt.axis([np.min(np.squeeze(self.args[2*u])), np.max(np.squeeze(self.args[2*u])), np.min(np.squeeze(self.args[2*u+1])), np.max(np.squeeze(self.args[2*u+1]))]) self.curraxis = self.axes[idx_0] exec('self.rendering_plt(self.line' + str(u) + ')') except TypeError: print('toto444') self.curraxe = 0 self.curraxis = self.axes exec('self.line' + str(self.curraxe) + '=self.axes.' + self.plt_type[0] + '(np.squeeze(self.args[0]), ' + 'np.squeeze(self.args[1]))') plt.axis([np.min(np.squeeze(self.args[0])), np.max(np.squeeze(self.args[0])), np.nanmin(np.squeeze(self.args[1])), np.nanmax(np.squeeze(self.args[1]))]) exec('self.rendering_plt(self.line' + str(self.curraxe) + ')') def imagesplot(self): try: len(self.axes) print('toto') test1 = np.arange(np.size(self.axes)) test2 = np.reshape(test1, np.shape(self.axes)) for u in range(0, len(self.plt_type)): self.curraxe = u idx_ = np.where(test2 == u) idx_0 = list(idx_[0])[0] x = self.x[u] y = self.y[u] X, Y = np.meshgrid(x, y) X = X.T Y = Y.T if len(idx_) > 1: idx_1 = list(idx_[1])[0] if self.plt_type[u] == 'imshow': vmin, vmax = self.set_histogram(self.args[u]) exec('self.line' + str(u) + '=self.axes[idx_0,idx_1].' + self.plt_type[u] + '(np.squeeze(self.args[u]), ' + 'clim=[vmin,vmax],origin="lower", ' + 'extent=[np.nanmin(x),np.nanmax(x), ' + 'np.nanmin(y),np.nanmax(y)])') self.curraxis = self.axes[idx_0, idx_1] exec('self.rendering_plt(self.line' + str(u) + ')') else: vmin, vmax = self.set_histogram(self.args[u]) exec('self.line' + str(u) + '=self.axes[idx_0,idx_1].' + self.plt_type[u] + '(Y,X,np.squeeze(self.args[u]), ' + 'clim=[vmin,vmax])') try: exec('self.line' + str(u) + '.axes.invert_yaxis()') except(AttributeError): exec('self.line' + str(u) + '.ax.invert_yaxis()') self.curraxis = self.axes[idx_0, idx_1] exec('self.rendering_plt(self.line' + str(u) + ')') else: if self.plt_type[u] == 'imshow': vmin, vmax = self.set_histogram(self.args[u]) print('xmin = {}, xmax={}, ' + 'xmin = {}, xmax={}'.format(np.nanmin(y), np.nanmax(y), np.nanmin(x), np.nanmax(x))) exec('self.line' + str(u) + '=self.axes[idx_0].' + self.plt_type[u] + '(np.squeeze(self.args[u]), ' + 'clim=[vmin,vmax],origin="lower", ' + 'extent=[np.nanmin(y),np.nanmax(y), ' + 'np.nanmin(x),np.nanmax(x)])') self.curraxis = self.axes[idx_0] exec('self.rendering_plt(self.line' + str(u) + ')') else: vmin, vmax = self.set_histogram(self.args[u]) print('vmin = {}, vmax={}'.format(vmin, vmax)) exec('self.line' + str(u) + '=self.axes[idx_0].' + self.plt_type[u] + '(Y,X,np.squeeze(self.args[u]), ' + 'clim=[vmin,vmax])') exec('self.line' + str(u) + '.set_clim(vmin,vmax)') try: exec('self.line' + str(u) + '.axes.invert_yaxis()') except(AttributeError): exec('self.line' + str(u) + '.ax.invert_yaxis()') self.curraxis = self.axes[idx_0] exec('self.rendering_plt(self.line' + str(u) + ')') except TypeError as e: print('error:{}'.format(e)) print('toto444') x = self.x y = self.y X, Y = np.meshgrid(x, y) X = X.T Y = Y.T vmin, vmax = self.set_histogram(self.args[0]) if self.plt_type[0] == 'imshow': self.curraxe = 0 self.curraxis = self.axes exec('self.line' + str(self.curraxe) + '=self.axes.' + self.plt_type[0] + '(np.squeeze(self.args[0]), ' + 'clim=[vmin, vmax], origin="lower", ' + 'extent=[np.nanmin(x), np.nanmax(x), ' + 'np.nanmin(y), np.nanmax(y)])') exec('self.rendering_plt(self.line' + str(self.curraxe) + ')') else: print('toto0') self.curraxe = 0 self.curraxis = self.axes exec('self.line' + str(self.curraxe) + '=self.axes.' + self.plt_type[0] + '(Y, X, np.squeeze(self.args[0]), ' + 'clim=[vmin, vmax])') try: exec('self.line' + str(self.curraxe) + '.axes.invert_yaxis()') except(AttributeError): exec('self.line' + str(self.curraxe) + '.ax.invert_yaxis()') exec('self.rendering_plt(self.line' + str(self.curraxe) + ')') def reject_outliers(data, m=2.): d = np.abs(data - np.nanmedian(data)) mdev = np.nanmedian(d) s = d / mdev if mdev else 0. data[s < m] = np.NaN return data def rendering_plt(self, line=None): if line is None: line = self.line for k, v in self.kwargs.items(): try: exec('plt.setp(self.line' + str(self.curraxe) + ',' + k + '=v[self.curraxe])') print(k) print(v) except AttributeError or IndexError: print('before pass') pass try: exec('self.curraxis.set_' + k + '(v[self.curraxe])') except AttributeError or IndexError: pass return self def set_histogram(self, a, curs=0): a[np.where(np.isinf(a))] = np.NaN n_cl = 500 # a[np.where(np.abs(a)<se)] = np.NaN num, bins = list(np.histogram(a[np.where(np.isnan(a) == False)], n_cl)) bins = bins[0: -1] + 0.5 * (bins[1] - bins[0]) k, = np.where(num == np.max(num)) _k = 1 # print('Im here {}'.format(k)) # print('Im num {}'.format(num)) try: if k[0] == 0: k[0] = 1 _k = 0 k2, = np.where(num[k[0]:] < .1 * num[k[0]-1]) # print('Im frfr {}'.format(_k)) # print('Im k2k2 {}'.format(k2)) else: k2, = np.where(num[k[0]:] < .01 * num[k[0]]) if np.min(k2) < 5: # print('Im gugu {}'.format(k2)) from scipy import signal if curs < 100: return self.set_histogram(signal.medfilt2d(a, kernel_size=5), curs=curs+1) if _k == 0: vmin = 0 else: vmin = bins[np.max([k[0] - np.min(k2), 0])] vmax = bins[k[0] + np.min(k2)] except ValueError as e: print('error with histogramm :{}'.format(e)) vmin = -100 vmax = -50 return vmin, vmax def c_lim(self, a, b): tu = [] [tu.append(k) for k in self.__dict__.keys() if k[0: 4] == 'line'] for u in range(len(tu)): exec('self.' + tu[u] + '.set_clim(a,b)') return def xy_lim(self, a, b, xy): exec('self.axes.set_' + xy + 'lim(a,b)') return