#!/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