diff --git a/wafo/containers.py b/wafo/containers.py index ad66795..7e779c3 100644 --- a/wafo/containers.py +++ b/wafo/containers.py @@ -1,8 +1,8 @@ -from __future__ import absolute_import +from __future__ import absolute_import, division, print_function import warnings from wafo.graphutil import cltext from wafo.plotbackend import plotbackend as plt -from time import gmtime, strftime +from wafo.misc import now import numpy as np from scipy.integrate.quadrature import cumtrapz # @UnresolvedImport from scipy import interpolate @@ -17,21 +17,22 @@ def empty_copy(obj): def __init__(self): pass newcopy = Empty() + # pylint: disable=attribute-defined-outside-init newcopy.__class__ = obj.__class__ return newcopy -def now(): - ''' - Return current date and time as a string - ''' - return strftime("%a, %d %b %Y %H:%M:%S", gmtime()) +def _set_seed(iseed): + if iseed is not None: + try: + np.random.set_state(iseed) + except ValueError: + np.random.seed(iseed) class PlotData(object): - ''' - Container class for data with interpolation and plotting methods + """Container class for data with interpolation and plotting methods. Member variables ---------------- @@ -69,7 +70,7 @@ class PlotData(object): >>> h = d3.plot() # plot data, CI red dotted line >>> h = d3.plot(plot_args_children=['b--']) # CI with blue dashed line - ''' + """ def __init__(self, data=None, args=None, **kwds): self.data = data @@ -92,8 +93,7 @@ class PlotData(object): return newcopy def eval_points(self, *points, **kwds): - ''' - Interpolate data at points + """Interpolate data at points. Parameters ---------- @@ -136,7 +136,8 @@ class PlotData(object): See also -------- scipy.interpolate.griddata - ''' + + """ options = dict(method='linear') options.update(**kwds) if isinstance(self.args, (list, tuple)): # Multidimensional data diff --git a/wafo/fig.py b/wafo/fig.py index a379349..cb7d76b 100644 --- a/wafo/fig.py +++ b/wafo/fig.py @@ -1,3 +1,4 @@ +# /usr/bin/env python ''' Module FIG ------------ @@ -7,7 +8,7 @@ pylab or enthought.mayavi.mlab on the windows platform. Figure manipulation involves maximization, minimization, hiding, closing, stacking or tiling. -This module assumes that the figures are uniquely numbered in the following way: +It is assumed that the figures are uniquely numbered in the following way: Figure 1 Figure 2 .... @@ -33,247 +34,338 @@ Example >>> fig.close('all') ''' -#!/usr/bin/env python -from __future__ import division +from __future__ import absolute_import, division, print_function # import win32api import win32gui import win32con -import msvcrt +import wx import numpy +from win32gui import (EnumWindows, MoveWindow, GetWindowRect, FindWindow, + ShowWindow, BringWindowToTop) + __all__ = ['close', 'cycle', 'hide', 'keep', 'maximize', 'minimize', 'pile', - 'restore', 'stack', 'tile'] + 'restore', 'stack', 'tile', 'find_all_figure_numbers', 'set_size'] # Figure format strings to recognize in window title -_FIG_FORMATS = ('Figure', 'TVTK Scene', 'Chaco Plot Window: Figure') +FIGURE_TITLE_FORMATS = ('Figure', 'TVTK Scene', 'Chaco Plot Window: Figure') _SCREENSIZE = None -def _getScreenSize(wnds): - ''' Return screen size X,Y,W,H +class CycleDialog(wx.Dialog): + + def _get_buttons(self): + hbox = wx.BoxSizer(wx.HORIZONTAL) + buttons = ['Forward', 'Back', 'Cancel'] + callbacks = [self.on_forward, self.on_backward, self.on_cancel] + for button, callback in zip(buttons, callbacks): + button = wx.Button(self, -1, button, size=(70, 30)) + self.Bind(wx.EVT_BUTTON, callback, button) + hbox.Add(button, 1, wx.ALIGN_CENTER) + return hbox + + def _get_message(self): + label = ('Press back or forward to display previous or next figure(s),' + ' respectively. Press cancel to quit.') + message = wx.StaticText(self, label=label, size=(240, 25)) + return message + + def __init__(self, parent, interval=None, title='Cycle dialog'): + super(CycleDialog, self).__init__(parent, title=title, size=(260, 130)) + if isinstance(interval, (float, int)): + self.interval_milli_sec = interval * 1000 + else: + self.interval_milli_sec = 30 + + self.timer = wx.Timer(self) + self.Bind(wx.EVT_TIMER, self.on_forward, self.timer) + + vbox = wx.BoxSizer(wx.VERTICAL) + vbox.Add(self._get_message(), 0, wx.ALIGN_CENTER | wx.TOP, 20) + vbox.Add(self._get_buttons(), 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 10) + self.SetSizer(vbox) + + def ShowModal(self, *args, **kwargs): + self.timer.Start(self.interval_milli_sec, oneShot=True) + return super(CycleDialog, self).ShowModal(*args, **kwargs) + + def on_forward(self, evt): + self.EndModal(wx.ID_FORWARD) + + def on_backward(self, evt): + self.EndModal(wx.ID_BACKWARD) + + def on_cancel(self, evt): + self.EndModal(wx.ID_CANCEL) + + +def _get_cycle_dialog(parent=None, interval=None): + app = wx.GetApp() + if not app: + app = wx.App(redirect=False) + frame = wx.Frame(None) + app.SetTopWindow(frame) + dlg = CycleDialog(parent, interval) + return dlg + + +def get_window_position_and_size(window_handle): + pos = GetWindowRect(window_handle) + return pos[0], pos[1], pos[2] - pos[0], pos[3] - pos[1] - Returns - -------- - X Specifies the new position of the left side of the screen. - Y Specifies the new position of the top of the screen. - W Specifies the new width of the screen. - H Specifies the new height of the screen. + +def get_screen_position_and_size(window_handles): + """Return screen position; X, Y and size; width, height. Parameters ---------- - wnds: list of handles to open figures + window_handles: list of handles to open window figures (Note: only needed the first time) - ''' + Returns + -------- + X : coordinate of the left side of the screen. + Y : coordinate of the top of the screen. + width : screen horizontal size + height : screen vertical size + """ + # pylint: disable=global-statement global _SCREENSIZE if _SCREENSIZE is None: - MoveWindow = win32gui.MoveWindow - GetWindowRect = win32gui.GetWindowRect - SW_MAXIMIZE = win32con.SW_SHOWMAXIMIZED - hwnd = [wnds[0]] - pos = list(GetWindowRect(hwnd[0])) - pos[3] -= pos[1] - pos[2] -= pos[0] - _show_windows(hwnd, SW_MAXIMIZE) - _SCREENSIZE = list(GetWindowRect(hwnd[0])) # Screen size - _SCREENSIZE[3] -= _SCREENSIZE[1] - _SCREENSIZE[2] -= _SCREENSIZE[0] - _SCREENSIZE = tuple(_SCREENSIZE) + window_handle = window_handles[0] + pos = get_window_position_and_size(window_handle) + _show_windows((window_handle,), win32con.SW_SHOWMAXIMIZED) + _SCREENSIZE = get_window_position_and_size(window_handle) + MoveWindow(window_handle, pos[0], pos[1], pos[2], pos[3], 1) + return _SCREENSIZE - MoveWindow(hwnd[0], pos[0], pos[1], pos[2], pos[3], 1) - return list(_SCREENSIZE) +def _get_screen_size(wnds): + screen_width, screen_height = get_screen_position_and_size(wnds)[2:4] + return screen_width, screen_height -def _windowEnumerationHandler(hwnd, resultList): - '''Pass to win32gui.EnumWindows() to generate list of window handle, - window text tuples. - ''' +def _windowEnumerationHandler(handle, result_list): + """Pass to win32gui.EnumWindows() to generate list of window handle, window + text tuples.""" + # pylint: disable=no-member + if win32gui.IsWindowVisible(handle): + result_list.append((handle, win32gui.GetWindowText(handle))) - resultList.append((hwnd, win32gui.GetWindowText(hwnd))) +def _find_window_handles_and_titles(wantedTitle=None): + """Return list of window handle and window title tuples. -def _findTopWindows(wantedTitle=None): - ''' Return list of window handle and window title tuples + Parameter + --------- + wantedTitle: - @param wantedTitle: - ''' - topWindows = [] - win32gui.EnumWindows(_windowEnumerationHandler, topWindows) + """ + handles_n_titles = [] + EnumWindows(_windowEnumerationHandler, handles_n_titles) if wantedTitle is None: - return topWindows + return handles_n_titles else: - return [(hwnd, windowTxt) for hwnd, windowTxt in topWindows - if windowTxt.startswith(wantedTitle)] - - -def findallfigs(): - ''' - Return list of all figure numbers - ''' - figs = [] - global _FIG_FORMATS - for wantedTitle in _FIG_FORMATS: - windowList = _findTopWindows(wantedTitle) - for unused_hwnd, wndTitle in windowList: + return [(handle, title) + for handle, title in handles_n_titles + if title.startswith(wantedTitle)] + + +def find_figure_handles(*figure_numbers): + """Find figure handles from figure numbers.""" + wnd_handles = [] + for figure_number in _parse_figure_numbers(*figure_numbers): + for format_ in FIGURE_TITLE_FORMATS: + winTitle = format_ + ' %d' % figure_number + handle = FindWindow(None, winTitle) + if not handle == 0: + wnd_handles.append(handle) + return wnd_handles + + +def find_all_figure_numbers(): + """Return list of all figure numbers. + + Example + ------- + >>> import fig + >>> import pylab as p + >>> for ix in range(5): + ... f = p.figure(ix) + ... p.draw() + + fig.find_all_figure_numbers() + [0, 1, 2, 3, 4] + + >>> fig.close() + + """ + figure_numbers = [] + for wantedTitle in FIGURE_TITLE_FORMATS: + handles_n_titles = _find_window_handles_and_titles(wantedTitle) + for _handle, title in handles_n_titles: try: - fig = int(wndTitle.split()[-1]) - figs.append(fig) - except: + number = int(title.split()[-1]) + figure_numbers.append(number) + except (TypeError, ValueError): pass - figs.sort() - return figs + # pylint: disable=no-member + return numpy.unique(figure_numbers).tolist() -def _figparse(*args): - figs = [] +def _parse_figure_numbers(*args): + figure_numbers = [] for arg in args: if isinstance(arg, (list, tuple, set)): for val in arg: - figs.append(int(val)) + figure_numbers.append(int(val)) elif isinstance(arg, int): - figs.append(arg) + figure_numbers.append(arg) elif arg == 'all': - figs = 'all' + figure_numbers = find_all_figure_numbers() break else: raise TypeError('Only integers arguments accepted!') - # raise TypeError('Unrecognized argument type (%s)!'%type(arg)) - if len(figs) == 0 or figs == 'all': - figs = findallfigs() - return figs + if len(figure_numbers) == 0: + figure_numbers = find_all_figure_numbers() + return figure_numbers -def _fig2wnd(figs): - ''' Find figure handle from figure number - ''' - FindWindow = win32gui.FindWindow - wnd_handles = [] - global _FIG_FORMATS - for fig in figs: - for format_ in _FIG_FORMATS: - winTitle = format_ + ' %d' % fig - hwnd = FindWindow(None, winTitle) - if not hwnd == 0: - wnd_handles.append(hwnd) - return wnd_handles +def _show_figure(figure_numbers, command): + """Sets the specified figure's show state. + Parameters + ---------- + figure_numbers: list of figure numbers + command: one of following commands: + SW_FORCEMINIMIZE: + Minimizes a window, even if the thread that owns the window is not + responding. This flag should only be used when minimizing windows + from a different thread. + SW_HIDE: + Hides the window and activates another window. + SW_MAXIMIZE: + Maximizes the specified window. + SW_MINIMIZE: + Minimizes the specified window and activates the next top-level window + in the Z order. + SW_RESTORE: + Activates and displays the window. If the window is minimized or + maximized, the system restores it to its original size and position. + An application should specify this flag when restoring a minimized + window. + SW_SHOW: + Activates the window and displays it in its current size and position. + SW_SHOWDEFAULT: + Sets the show state based on the SW_ value specified in the STARTUPINFO + structure passed to the CreateProcess function by the program that + started the application. + SW_SHOWMAXIMIZED: + Activates the window and displays it as a maximized window. + SW_SHOWMINIMIZED: + Activates the window and displays it as a minimized window. + SW_SHOWMINNOACTIVE: + Displays the window as a minimized window. This value is similar to + SW_SHOWMINIMIZED, except the window is not activated. + SW_SHOWNA: + Displays the window in its current size and position. This value is + similar to SW_SHOW, except the window is not activated. + SW_SHOWNOACTIVATE: + Displays a window in its most recent size and position. This value is + similar to SW_SHOWNORMAL, except the window is not actived. + SW_SHOWNORMAL: + Activates and displays a window. If the window is minimized or + maximized, the system restores it to its original size and position. + An application should specify this flag when displaying the window for + the first time. -def _show_figure(figs, cmdshow): - ''' sets the specified figure's show state. - - @param figs: vector for figure numbers - @param cmdshow: one of following commands: - SW_FORCEMINIMIZE: Minimizes a window, even if the thread that owns the - window is not responding. This flag should only be used - when minimizing windows from a different thread. - SW_HIDE: Hides the window and activates another window. - SW_MAXIMIZE: Maximizes the specified window. - SW_MINIMIZE: Minimizes the specified window and activates the next - top-level window in the Z order. - SW_RESTORE: Activates and displays the window. If the window is - minimized or maximized, the system restores it to its - original size and position. An application should - specify this flag when restoring a minimized window. - SW_SHOW: Activates the window and displays it in its current size - and position. - SW_SHOWDEFAULT: Sets the show state based on the SW_ value specified in the - STARTUPINFO structure passed to the CreateProcess function - by the program that started the application. - SW_SHOWMAXIMIZED: Activates the window and displays it as a maximized - window. - SW_SHOWMINIMIZED: Activates the window and displays it as a minimized + """ + for number in _parse_figure_numbers(*figure_numbers): + for format_ in FIGURE_TITLE_FORMATS: + title = format_ + ' %d' % number + handle = FindWindow(None, title) + if not handle == 0: + BringWindowToTop(handle) + ShowWindow(handle, command) + + +def _show_windows(handles, command, redraw_now=False): + """Sets the specified window's show state. + + Parameters + ---------- + handles: list of window handles + command: one of following commands: + SW_FORCEMINIMIZE: + Minimizes a window, even if the thread that owns the window is not + responding. This flag should only be used when minimizing windows + from a different thread. + SW_HIDE: + Hides the window and activates another window. + SW_MAXIMIZE: + Maximizes the specified window. + SW_MINIMIZE: + Minimizes the specified window and activates the next top-level window + in the Z order. + SW_RESTORE: + Activates and displays the window. If the window is minimized or + maximized, the system restores it to its original size and position. + An application should specify this flag when restoring a minimized window. - SW_SHOWMINNOACTIVE: Displays the window as a minimized window. This value - is similar to SW_SHOWMINIMIZED, except the window is not - activated. - SW_SHOWNA: Displays the window in its current size and position. This - value is similar to SW_SHOW, except the window is not activated. - SW_SHOWNOACTIVATE: Displays a window in its most recent size and position. - This value is similar to SW_SHOWNORMAL, except the window - is not actived. - SW_SHOWNORMAL: Activates and displays a window. If the window is minimized - or maximized, the system restores it to its original size and - position. An application should specify this flag when - displaying the window for the first time. - ''' - BringWindowToTop = win32gui.BringWindowToTop - FindWindow = win32gui.FindWindow - ShowWindow = win32gui.ShowWindow - global _FIG_FORMATS - for fig in figs: - for format_ in _FIG_FORMATS: - winTitle = format_ + ' %d' % fig - hwnd = FindWindow(None, winTitle) - if not hwnd == 0: - # ShowWindow(hwnd,cmdshow) - BringWindowToTop(hwnd) - ShowWindow(hwnd, cmdshow) - - -def _show_windows(wnds, cmdshow): - ''' sets the specified window's show state. - - @param wnds: list of window handles numbers - @param cmdshow: one of following commands: - SW_FORCEMINIMIZE: Minimizes a window, even if the thread that owns the - window is not responding. This flag should only be used - when minimizing windows from a different thread. - SW_HIDE: Hides the window and activates another window. - SW_MAXIMIZE: Maximizes the specified window. - SW_MINIMIZE: Minimizes the specified window and activates the next - top-level window in the Z order. - SW_RESTORE: Activates and displays the window. If the window is - minimized or maximized, the system restores it to its original - size and position. An application should specify this flag when - restoring a minimized window. - SW_SHOW: Activates the window and displays it in its current size and - position. - SW_SHOWDEFAULT: Sets the show state based on the SW_ value specified in - the STARTUPINFO structure passed to the CreateProcess - function by the program that started the application. - SW_SHOWMAXIMIZED: Activates the window and displays it as a maximized - window. - SW_SHOWMINIMIZED: Activates the window and displays it as a minimized - window. - SW_SHOWMINNOACTIVE: Displays the window as a minimized window. This - value is similar to SW_SHOWMINIMIZED, except the window - is not activated. - SW_SHOWNA: Displays the window in its current size and position. This - value is similar to SW_SHOW, except the window is not activated. - SW_SHOWNOACTIVATE: Displays a window in its most recent size and position. - This value is similar to SW_SHOWNORMAL, except the - window is not actived. - SW_SHOWNORMAL: Activates and displays a window. If the window is minimized - or maximized, the system restores it to its original size and - position. An application should specify this flag when - displaying the window for the first time. - ''' - - ShowWindow = win32gui.ShowWindow - BringWindowToTop = win32gui.BringWindowToTop - for hwnd in wnds: - if not hwnd == 0: - # ShowWindow(hwnd,cmdshow) - BringWindowToTop(hwnd) - ShowWindow(hwnd, cmdshow) - - -def keep(*figs): - ''' Keeps figure windows of your choice and closes the rest. + SW_SHOW: + Activates the window and displays it in its current size and position. + SW_SHOWDEFAULT: + Sets the show state based on the SW_ value specified in the STARTUPINFO + structure passed to the CreateProcess function by the program that + started the application. + SW_SHOWMAXIMIZED: + Activates the window and displays it as a maximized window. + SW_SHOWMINIMIZED: + Activates the window and displays it as a minimized window. + SW_SHOWMINNOACTIVE: + Displays the window as a minimized window. This value is similar to + SW_SHOWMINIMIZED, except the window is not activated. + SW_SHOWNA: + Displays the window in its current size and position. This value is + similar to SW_SHOW, except the window is not activated. + SW_SHOWNOACTIVATE: + Displays a window in its most recent size and position. This value is + similar to SW_SHOWNORMAL, except the window is not actived. + SW_SHOWNORMAL: + Activates and displays a window. If the window is minimized or + maximized, the system restores it to its original size and position. + An application should specify this flag when displaying the window for + the first time. + + redraw_now : + + """ + # pylint: disable=no-member + for handle in handles: + if not handle == 0: + BringWindowToTop(handle) + ShowWindow(handle, command) + if redraw_now: + rect = GetWindowRect(handle) + win32gui.RedrawWindow(handle, rect, None, win32con.RDW_UPDATENOW) + + +def keep(*figure_numbers): + """Keeps figure windows of your choice and closes the rest. Parameters ---------- - figs : list of integers specifying which figures to keep. + figure_numbers : list of integers specifying which figures to keep. Example: -------- # keep only figures 1,2,3,5 and 7 >>> import pylab as p >>> import wafo.fig as fig - >>> for ix in range(10): f = p.figure(ix) + >>> for ix in range(10): + ... f = p.figure(ix) >>> fig.keep( range(1,4), 5, 7) or @@ -282,10 +374,11 @@ def keep(*figs): See also -------- - pyfig.close - ''' + fig.close + + """ figs2keep = [] - for fig in figs: + for fig in figure_numbers: if isinstance(fig, (list, tuple, set)): for val in fig: figs2keep.append(int(val)) @@ -295,28 +388,25 @@ def keep(*figs): raise TypeError('Only integers arguments accepted!') if len(figs2keep) > 0: - allfigs = set(findallfigs()) - -# Remove figure handles in the "keep" list + allfigs = set(find_all_figure_numbers()) figs2delete = allfigs.difference(figs2keep) close(figs2delete) - # for fig in figs2delete: - # close(fig) -def close(*figs): +def close(*figure_numbers): """ Close figure window(s) Parameters ---------- - figs : list of integers or string + figure_numbers : list of integers or string specifying which figures to close (default 'all'). Examples -------- >>> import pylab as p >>> import wafo.fig as fig - >>> for ix in range(5): f = p.figure(ix) + >>> for ix in range(5): + ... f = p.figure(ix) >>> fig.close(3,4) # close figure 3 and 4 >>> fig.close('all') # close all remaining figures @@ -325,20 +415,21 @@ def close(*figs): See also -------- - pyfig.keep + fig.keep + """ - figlist = _figparse(*figs) - wnds = _fig2wnd(figlist) - for wnd in wnds: - win32gui.SendMessage(wnd, win32con.WM_CLOSE, 0, 0) + # pylint: disable=no-member + for handle in find_figure_handles(*figure_numbers): + if win32gui.SendMessage(handle, win32con.WM_CLOSE, 0, 0): + win32gui.SendMessage(handle, win32con.WM_DESTROY, 0, 0) -def restore(*figs): - '''Restore figures window size and position to its default value. +def restore(*figure_numbers): + """Restore figures window size and position to its default value. Parameters ---------- - figs : list of integers or string + figure_numbers : list of integers or string specifying which figures to restor (default 'all'). Description @@ -350,7 +441,8 @@ def restore(*figs): --------- >>> import pylab as p >>> import wafo.fig as fig - >>> for ix in range(5): f = p.figure(ix) + >>> for ix in range(5): + ... f = p.figure(ix) >>> fig.restore('all') #Restores all figures >>> fig.restore() #same as restore('all') >>> fig.restore(p.gcf().number) #Restores the current figure @@ -365,27 +457,28 @@ def restore(*figs): -------- fig.close, fig.keep - ''' - - figlist = _figparse(*figs) - SW_RESTORE = win32con.SW_SHOWNORMAL # SW_RESTORE - _show_figure(figlist, SW_RESTORE) + """ + SW_RESTORE = win32con.SW_RESTORE + # SW_RESTORE = win32con.SW_SHOWDEFAULT + # SW_RESTORE = win32con.SW_SHOWNORMAL + _show_figure(figure_numbers, SW_RESTORE) -def hide(*figs): - '''hide figure(s) window size +def hide(*figure_numbers): + """hide figure(s) window. Parameters ---------- - figs : list of integers or string + figure_numbers : list of integers or string specifying which figures to hide (default 'all'). Examples: -------- - >>> import wafo.fig as fig + >>> import wafo.fig as fig >>> import pylab as p - >>> for ix in range(5): f = p.figure(ix) + >>> for ix in range(5): + ... f = p.figure(ix) >>> fig.hide('all') #hides all unhidden figures >>> fig.hide() #same as hide('all') >>> fig.hide(p.gcf().number) #hides the current figure @@ -394,34 +487,33 @@ def hide(*figs): or alternatively fig.hide(2, 4) + >>> fig.restore(list(range(5))) >>> fig.close() See also -------- - pyfig.cycle, - pyfig.keep, - pyfig.restore - ''' + fig.cycle, + fig.keep, + fig.restore - figlist = _figparse(*figs) - SW_HIDE = win32con.SW_HIDE - # SW_hide = win32con.SW_hide - _show_figure(figlist, SW_HIDE) + """ + _show_figure(figure_numbers, win32con.SW_HIDE) -def minimize(*figs): - '''Minimize figure(s) window size +def minimize(*figure_numbers): + """Minimize figure(s) window size. Parameters ---------- - figs : list of integers or string + figure_numbers : list of integers or string specifying which figures to minimize (default 'all'). Examples: --------- >>> import wafo.fig as fig >>> import pylab as p - >>> for ix in range(5): f = p.figure(ix) + >>> for ix in range(5): + ... f = p.figure(ix) >>> fig.minimize('all') #Minimizes all unhidden figures >>> fig.minimize() #same as minimize('all') >>> fig.minimize(p.gcf().number) #Minimizes the current figure @@ -434,29 +526,28 @@ def minimize(*figs): See also -------- - pyfig.cycle, - pyfig.keep, - pyfig.restore - ''' + fig.cycle, + fig.keep, + fig.restore - figlist = _figparse(*figs) - SW_MINIMIZE = win32con.SW_SHOWMINIMIZED - _show_figure(figlist, SW_MINIMIZE) + """ + _show_figure(figure_numbers, win32con.SW_SHOWMINIMIZED) -def maximize(*figs): - '''Maximize figure(s) window size +def maximize(*figure_numbers): + """Maximize figure(s) window size. Parameters ---------- - figs : list of integers or string + figure_numbers : list of integers or string specifying which figures to maximize (default 'all'). Examples: --------- >>> import pylab as p >>> import wafo.fig as fig - >>> for ix in range(5): f = p.figure(ix) + >>> for ix in range(5): + ... f = p.figure(ix) >>> fig.maximize('all') #Maximizes all unhidden figures >>> fig.maximize() #same as maximize('all') >>> fig.maximize(p.gcf().number) #Maximizes the current figure @@ -469,24 +560,25 @@ def maximize(*figs): See also -------- - pyfig.cycle, - pyfig.keep, - pyfig.restore - ''' + fig.cycle, + fig.keep, + fig.restore - figlist = _figparse(*figs) - SW_MAXIMIZE = win32con.SW_SHOWMAXIMIZED - # SW_MAXIMIZE = win32con.SW_MAXIMIZE - _show_figure(figlist, SW_MAXIMIZE) + """ + _show_figure(figure_numbers, win32con.SW_SHOWMAXIMIZED) -def pile(*figs): - ''' Pile figure windows +def pile(*figure_numbers, **kwds): + """Pile figure windows. Parameters ---------- - figs : list of integers or string + figure_numbers : list of integers or string specifying which figures to pile (default 'all'). + kwds : dict with the following keys + position : + width : + height : Description ------------- @@ -498,40 +590,90 @@ def pile(*figs): -------- >>> import pylab as p >>> import wafo.fig as fig - >>> for ix in range(5): f = p.figure(ix) + >>> for ix in range(7): + ... f = p.figure(ix) >>> fig.pile() # pile all open figures >>> fig.pile(range(1,4), 5, 7) # pile figure 1,2,3,5 and 7 >>> fig.close() See also -------- - pyfig.cycle, pyfig.keep, pyfig.maximize, pyfig.restore, - pyfig.stack, pyfig.tile - ''' + fig.cycle, fig.keep, fig.maximize, fig.restore, + fig.stack, fig.tile - figlist = _figparse(*figs) - wnds = _fig2wnd(figlist) + """ + wnds = find_figure_handles(*figure_numbers) numfigs = len(wnds) if numfigs > 0: - pos = _getScreenSize(wnds) - pos[3] = int(pos[3] / 2) - pos[2] = int(pos[2] / 2.5) - pos[1] = int(pos[3] / 2) - pos[0] = int(pos[2] / 2) - BringWindowToTop = win32gui.BringWindowToTop - MoveWindow = win32gui.MoveWindow + screen_width, screen_height = _get_screen_size(wnds) + pos = kwds.get( + 'position', (int(screen_width / 5), int(screen_height / 4))) + width = kwds.get('width', int(screen_width / 2.5)) + height = kwds.get('height', int(screen_height / 2)) + for wnd in wnds: - MoveWindow(wnd, pos[0], pos[1], pos[2], pos[3], 1) + MoveWindow(wnd, pos[0], pos[1], width, height, 1) BringWindowToTop(wnd) -def stack(*figs): - ''' Stack figure windows +def set_size(*figure_numbers, **kwds): + """Set size for figure windows. + + Parameters + ---------- + figure_numbers : list of integers or string + specifying which figures to pile (default 'all'). + kwds : dict with the following keys + width : + height : + + Description + ------------- + Set size sets the size of all open figure windows. SET_SIZE(FIGS) + can be used to specify which figures that should be resized. + Figures are not sorted when specified. + + Example: + -------- + >>> import pylab as p + >>> import fig + >>> for ix in range(7): + ... f = p.figure(ix) + >>> fig.set_size(7, width=150, height=100) + >>> fig.set_size(range(1,4), 5,width=250, height=170) + >>> fig.close() + + See also + -------- + fig.cycle, fig.keep, fig.maximize, fig.restore, + fig.stack, fig.tile + + """ + handles = find_figure_handles(*figure_numbers) + numfigs = len(handles) + if numfigs > 0: + screen_width, screen_height = _get_screen_size(handles) + width = kwds.get('width', int(screen_width / 2.5)) + height = kwds.get('height', int(screen_height / 2)) + new_pos = kwds.get('position', None) + pos = new_pos + for handle in handles: + if not new_pos: + pos = get_window_position_and_size(handle) + MoveWindow(handle, pos[0], pos[1], width, height, 1) + BringWindowToTop(handle) + + +def stack(*figure_numbers, **kwds): + """Stack figure windows. Parameters ---------- - figs : list of integers or string + figure_numbers : list of integers or string specifying which figures to stack (default 'all'). + kwds : dict with the following keys + figs_per_stack : + number of figures per stack (default depends on screenheight) Description ----------- @@ -543,55 +685,45 @@ def stack(*figs): -------- >>> import pylab as p >>> import wafo.fig as fig - >>> for ix in range(5): f = p.figure(ix) + >>> for ix in range(7): + ... f = p.figure(ix) >>> fig.stack() # stack all open figures >>> fig.stack(range(1,4), 5, 7) # stack figure 1,2,3,5 and 7 >>> fig.close() See also -------- - pyfig.cycle, pyfig.keep, pyfig.maximize, pyfig.restore, - pyfig.pile, pyfig.tile - ''' + fig.cycle, fig.keep, fig.maximize, fig.restore, + fig.pile, fig.tile - figlist = _figparse(*figs) - wnds = _fig2wnd(figlist) + """ + wnds = find_figure_handles(*figure_numbers) numfigs = len(wnds) if numfigs > 0: - screenpos = _getScreenSize(wnds) - - maxfigs = numpy.fix(screenpos[3] / 20) - - if (numfigs > maxfigs): # figure limit check - print(' More than %d requested ' % maxfigs) - return - BringWindowToTop = win32gui.BringWindowToTop - MoveWindow = win32gui.MoveWindow - GetWindowRect = win32gui.GetWindowRect -# -# -# tile figures by postiion -# Location (1,1) is at bottom left corner -# - # print('Screensz = ',screenpos) + screenpos = get_screen_position_and_size(wnds) + y_step = 25 + x_step = border = 5 + + figs_per_stack = kwds.get( + 'figs_per_stack', + int(numpy.fix(0.7 * (screenpos[3] - border) / y_step))) + for iy in range(numfigs): - pos = list(GetWindowRect(wnds[iy])) - pos[3] -= pos[1] - pos[2] -= pos[0] + pos = get_window_position_and_size(wnds[iy]) # print('[x, y, w, h] = ', pos) - ypos = screenpos[1] + iy * 20 - # int(screenpos[3] - iy*20 -pos[3] -70) # figure location (row) - xpos = int(iy * 5 + 15 + screenpos[0]) # figure location (column) + ix = iy % figs_per_stack + ypos = int(screenpos[1] + ix * y_step + border) + xpos = int(screenpos[0] + ix * x_step + border) MoveWindow(wnds[iy], xpos, ypos, pos[2], pos[3], 1) BringWindowToTop(wnds[iy]) -def tile(*figs, **kwds): - ''' Tile figure windows. +def tile(*figure_numbers, **kwds): + """Tile figure windows. Parameters ---------- - figs : list of integers or string + figure_numbers : list of integers or string specifying which figures to tile (default 'all'). kwds : dict with key pairs specifying how many pairs of figures that are tiled at a time @@ -606,7 +738,8 @@ def tile(*figs, **kwds): -------- >>> import pylab as p >>> import wafo.fig as fig - >>> for ix in range(5): f = p.figure(ix) + >>> for ix in range(7): + ... f = p.figure(ix) >>> fig.tile() # tile all open figures >>> fig.tile( range(1,4), 5, 7) # tile figure 1,2,3,5 and 7 >>> fig.tile(range(1,11), pairs=2) # tile figure 1 to 10 two at a time @@ -615,14 +748,14 @@ def tile(*figs, **kwds): See also -------- - pyfig.cycle, pyfig.keep, pyfig.maximize, pyfig.minimize - pyfig.restore, pyfig.pile, pyfig.stack + fig.cycle, fig.keep, fig.maximize, fig.minimize + fig.restore, fig.pile, fig.stack - ''' - figlist = _figparse(*figs) - wnds = _fig2wnd(figlist) + """ + wnds = find_figure_handles(*figure_numbers) - nfigs = len(wnds) # Number of windows. + nfigs = len(wnds) + # Number of windows. if nfigs > 0: nfigspertile = kwds.get('pairs', nfigs) @@ -633,76 +766,54 @@ def tile(*figs, **kwds): nlayers = int(ceil(nfigs / nfigspertile)) - nh = int(ceil(sqrt(nfigspertile))) # Number of figures horisontally. - nv = int(ceil(nfigspertile / nh)) # Number of figures vertically. - - nh = maximum(nh, 2) - nv = maximum(nv, 2) - -# Get the screen size. -# -------------------- - - BringWindowToTop = win32gui.BringWindowToTop - MoveWindow = win32gui.MoveWindow - screenpos = _getScreenSize(wnds) - # scrdim = win32gui.GetWindowPlacement(h)[4] + # Number of figures horisontally. + nh = maximum(int(ceil(sqrt(nfigspertile))), 2) + # Number of figures vertically. + nv = maximum(int(ceil(nfigspertile / nh)), 2) - scrwid = screenpos[2] # Screen width. - scrhgt = screenpos[3] # Screen height. + screenpos = get_screen_position_and_size(wnds) + screen_width, screen_heigth = screenpos[2:4] -# -# The elements in the vector specifying the position. -# 1 - Window left position -# 2 - Window top position -# 3 - Window horizontal size -# 4 - Window vertical size -# ------------------------------------------ hspc = 10 # Horisontal space. topspc = 20 # Space above top figure. medspc = 10 # Space between figures. botspc = 20 # Space below bottom figure. - # print('scrwid = %d' % scrwid) - figwid = (scrwid - (nh + 1) * hspc) / nh - # print('figwid = %d' % figwid) - fighgt = (scrhgt - (topspc + botspc) - (nv - 1) * medspc) / nv + figwid = (screen_width - (nh + 1) * hspc) / nh + fighgt = (screen_heigth - (topspc + botspc) - (nv - 1) * medspc) / nv figwid = int(numpy.round(figwid)) fighgt = int(numpy.round(fighgt)) -# -# Put the figures where they belong. -# ----------------------------------- idx = 0 for unused_ix in range(nlayers): for row in range(nv): + figtop = int(screenpos[1] + topspc + row * (fighgt + medspc)) for col in range(nh): if (row) * nh + col < nfigspertile: if idx < nfigs: - figlft = int(screenpos[0] + (col + 1) * hspc + - col * figwid) - figtop = int(screenpos[1] + topspc + - row * (fighgt + medspc)) - # figpos = [ figlft figtop figwid fighgt ]; # Figure position. - # fighnd = FindWindow(0,'Figure %d' % figs[idx]) # Figure handle. + figlft = int( + screenpos[0] + (col + 1) * hspc + col * figwid) fighnd = wnds[idx] MoveWindow(fighnd, figlft, figtop, figwid, fighgt, - 1) # Set position. + 1) + # Set position. BringWindowToTop(fighnd) - # figure(figs[idx]) # Raise figure. idx += 1 -def cycle(*figs, **kwds): - ''' Cycle through figure windows. +class _CycleGenerator(object): + + """Cycle through figure windows. Parameters ---------- - figs : list of integers or string + figure_numbers : list of integers or string specifying which figures to cycle through (default 'all'). kwds : dict with the following keys pairs : number of figures to cycle in pairs (default 1) maximize: If True maximize figure when viewing (default False) + interval : pause interval in seconds Description ----------- @@ -711,147 +822,87 @@ def cycle(*figs, **kwds): figure(s) and press any other key to display next figure(s) When done, the figures are sorted in ascending order. - CYCLE(maximize=True) does the same thing, except that figures are - maximized. + CYCLE(maximize=True) does the same thing, except figures are maximized. CYCLE(pairs=2) cycle through all figures in pairs of 2. Examples: >>> import pylab as p >>> import wafo.fig as fig - >>> for ix in range(4): f = p.figure(ix) - - fig.cycle(range(3)) #Cycle trough figure 0 to 2 - fig.cycle(range(3) maximize=True) #Cycle trough figure 1 to 3 with figs - # maximized - fig.cycle() #Cycle through all figures one at a time - fig.tile(pairs=2) - fig.cycle(pairs=2) #Cycle through all figures two at a time + >>> for ix in range(4): + ... f = p.figure(ix) + + fig.cycle(range(3), interval=1) # Cycle trough figure 0 to 2 + + # Cycle trough figure 0 to 2 with figures maximized + fig.cycle(range(3), maximize=True, interval=1) + fig.cycle(interval=1) # Cycle through all figures one at a time + fig.tile(pairs=2, interval=1) + fig.cycle(pairs=2, interval=2) # Cycle through all figures two at a time + + fig.cycle(pairs=2) # Manually cycle through all figures two at a time >>> fig.close() See also -------- - pyfig.keep, pyfig.maximize, pyfig.restore, pyfig.pile, - pyfig.stack, pyfig.tile - ''' - # TODO : display is not updated for each cycle => function is useless - figlist = _figparse(*figs) - wnds = _fig2wnd(figlist) + fig.keep, fig.maximize, fig.restore, fig.pile, + fig.stack, fig.tile - numfigs = len(wnds) - if numfigs > 0: + """ + escape_key = chr(27) + backspace_key = chr(8) + + def __init__(self, **kwds): + self.dialog = None maximize = kwds.get('maximize', False) pairs = kwds.get('pairs', 1) - - if maximize or pairs is None: - nfigspercycle = 1 + self.interval = kwds.get('interval', 'user_defined') + self.nfigspercycle = 1 + if maximize: + self.command = win32con.SW_SHOWMAXIMIZED else: - nfigspercycle = pairs + self.command = win32con.SW_SHOWNORMAL + if pairs is not None: + self.nfigspercycle = pairs - # n = length(figs); - # nlayers = ceil(n/nfigspercycle); + def _set_options(self, kwds): + self.__init__(**kwds) - # Bring one figure up at a time. + def _iterate(self, handles): i = 0 - escape_key = chr(27) - backspace_key = chr(8) + numfigs = len(handles) + self.dialog = _get_cycle_dialog(parent=None, interval=self.interval) while 0 <= i and i < numfigs: - - if maximize: - cmdshow = win32con.SW_SHOWMAXIMIZED + iu = min(i + self.nfigspercycle, numfigs) + yield handles[i:iu] + i = self.next_index(i) + self.dialog.Destroy() + raise StopIteration + + def next_index(self, i): + result = self.dialog.ShowModal() + if result == wx.ID_FORWARD: + i += self.nfigspercycle + elif result == wx.ID_BACKWARD: + i -= self.nfigspercycle else: - cmdshow = win32con.SW_SHOWNORMAL + i = -1 + return i - iu = min(i + nfigspercycle, numfigs) - wnd = wnds[i:iu] - _show_windows(wnd, cmdshow) - - if i + nfigspercycle - 1 < numfigs: - print('Press escape to quit, backspace to display previous ' + - 'figure(s) and any other key to display next figure(s)') - - # time.sleep(0.5) - - B = msvcrt.getch() - - if maximize: # restore window position - _show_windows(wnd, win32con.SW_RESTORE) - - if B == backspace_key: # Back space - i -= nfigspercycle - elif B == escape_key: - break - else: - i += nfigspercycle + def __call__(self, *figure_numbers, **kwds): + handles = find_figure_handles(*figure_numbers) + numfigs = len(handles) + if numfigs > 0: + self._set_options(kwds) + for handle in self._iterate(handles): + _show_windows(handle, self.command, redraw_now=True) - # Sort the figures. - wnds.reverse() - _show_windows(wnds, win32con.SW_SHOWNORMAL) + _show_windows(handles, win32con.SW_SHOWNORMAL) +cycle = _CycleGenerator() -def test_docstrings(): - import doctest - doctest.testmod() if __name__ == '__main__': - test_docstrings() - - -# def _errcheck(result, func, args): -# if not result: -# raise WinError() -# return args -# -# def bring_window2top(): -# #WINUSERAPI BOOL WINAPI -# #GetWindowRect( -# # HWND hWnd, -# # LPRECT lpRect); -# # -# #Here is the wrapping with ctypes: -# NULL = 0 -# SW_HIDE = 0 -# SW_NORMAL = 1 -# SW_SHOWNORMAL = 1 -# SW_SHOWMINIMIZED = 2 -# SW_MAXIMIZE = 3 -# SW_SHOWMAXIMIZED = 3 -# SW_SHOWNOACTIVATE = 4 -# SW_SHOW= 5 -# SW_MINIMIZE = 6 -# SW_SHOWMINNOACTIVE= 7 -# SW_SHOWNA = 8 -# SW_RESTORE = 9 -# SW_SHOWDEFAULT = 10 -# SW_FORCEMINIMIZE = 11 -# SW_MAX = 11 -# -# -# #hwnd = FindWindow(windowname) -# from ctypes import POINTER, WINFUNCTYPE, windll, WinError -# from ctypes.wintypes import BOOL, HWND, RECT, LPCSTR, UINT, c_int -# #Not OK -# prototype0 = WINFUNCTYPE(HWND, LPCSTR,LPCSTR) -# paramflags = (1, "lpClassName"), (1, "lpWindowName") -# FindWindow = prototype0(("FindWindow", windll.user32), paramflags) -# -# # OK -# prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT)) -# paramflags = (1, "hwnd"), (2, "lprect") -# GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags) -# GetWindowRect.errcheck = _errcheck -# -# #BringWindowToTop(hwnd) -# prototype2 = WINFUNCTYPE(BOOL,HWND) -# paramflags = (1, "hwnd"), -# #Not Ok. -# BringWindowToTop = prototype2(("BringWindowToTop", windll.user32), -# paramflags) -# # Ok -# CloseWindow = prototype2(("CloseWindow", windll.user32), paramflags) -# #Not ok -# prototype3 = WINFUNCTYPE(BOOL, HWND, POINTER(UINT)) -# paramflags = (1, "hwnd"), (1, "ncmdshow") -# ShowWindow = prototype3(("ShowWindow", windll.user32),paramflags) -# import win32gui -# h = win32gui.FindWindow(None,'PyLab') -# win32gui.ShowWindow(h,) + from utilities.testing import test_docstrings + import matplotlib + matplotlib.interactive(True) + test_docstrings(__file__) diff --git a/wafo/graphutil.py b/wafo/graphutil.py index b288dd6..a2d55b0 100644 --- a/wafo/graphutil.py +++ b/wafo/graphutil.py @@ -5,12 +5,12 @@ Created on 20. jan. 2011 license BSD ''' -from __future__ import absolute_import, division +from __future__ import absolute_import, division, print_function import warnings import numpy as np from .plotbackend import plotbackend from matplotlib import mlab -__all__ = ['cltext', 'tallibing', 'test_docstrings'] +__all__ = ['cltext', 'epcolor', 'tallibing', 'test_docstrings'] _TALLIBING_GID = 'TALLIBING' _CLTEXT_GID = 'CLTEXT' @@ -108,9 +108,11 @@ def cltext(levels, percent=False, n=4, xs=0.036, ys=0.94, zs=0, figure=None, >>> import wafo.demos as wd >>> import pylab as plt >>> x,y,z = wd.peaks(); + >>> h = plt.contour(x,y,z) + >>> h = wg.cltext(h.levels) + + >>> plt.close('all') - h = plt.contour(x,y,z) - h = wg.cltext(h.levels) plt.show() ''' # TODO : Make it work like legend does (but without the box): include @@ -142,7 +144,6 @@ def cltext(levels, percent=False, n=4, xs=0.036, ys=0.94, zs=0, figure=None, titletxt = 'Level curves enclosing:' else: titletxt = 'Level curves at:' - format_ = '%0.' + ('%d' % n) + 'g\n' cltxt = ''.join([format_ % level for level in clevels.tolist()]) @@ -196,9 +197,10 @@ def tallibing(*args, **kwds): >>> import wafo.graphutil as wg >>> import wafo.demos as wd >>> [x,y,z] = wd.peaks(n=20) + >>> h = wg.pcolor(x,y,z) + >>> h = wg.tallibing(x,y,z) - h0 = wg.pcolor(x,y,z) - h1 = wg.tallibing(x,y,z) + pcolor(x,y,z); shading interp; See also -------- diff --git a/wafo/kdetools/demo.py b/wafo/kdetools/demo.py index a61cefa..4738278 100644 --- a/wafo/kdetools/demo.py +++ b/wafo/kdetools/demo.py @@ -246,7 +246,6 @@ def kreg_demo1(hs=None, fast=True, fun='hisj'): plt.plot(x, y2[0], 'm', label='statsmodel') plt.legend() - # plt.show() # print(kreg.tkde.tkde._inv_hs) # print(kreg.tkde.tkde.hs) diff --git a/wafo/kdetools/gridding.py b/wafo/kdetools/gridding.py index 6c95554..342e9b3 100644 --- a/wafo/kdetools/gridding.py +++ b/wafo/kdetools/gridding.py @@ -3,7 +3,7 @@ Created on 15. des. 2016 @author: pab ''' -from __future__ import division +from __future__ import absolute_import, division, print_function from scipy import sparse import numpy as np from wafo.testing import test_docstrings @@ -181,10 +181,10 @@ def accum(accmap, a, func=None, shape=None, fill_value=0, dtype=None): def create_array_of_python_lists(accmap, a, shape): vals = np.empty(shape, dtype='O') - for s in product(*[range(k) for k in shape]): + for s in product(*[np.arange(k) for k in shape]): vals[s] = [] - for s in product(*[range(k) for k in a.shape]): + for s in product(*[np.arange(k) for k in a.shape]): indx = tuple(accmap[s]) val = a[s] vals[indx].append(val) @@ -216,7 +216,7 @@ def accum(accmap, a, func=None, shape=None, fill_value=0, dtype=None): # Create the output array. out = np.empty(shape, dtype=dtype) - for s in product(*[range(k) for k in shape]): + for s in product(*[np.arange(k) for k in shape]): if vals[s] == []: out[s] = fill_value else: diff --git a/wafo/kdetools/kdetools.py b/wafo/kdetools/kdetools.py index 3e8f251..2ff312b 100644 --- a/wafo/kdetools/kdetools.py +++ b/wafo/kdetools/kdetools.py @@ -10,12 +10,12 @@ # Licence: LGPL # ------------------------------------------------------------------------- -from __future__ import absolute_import, division +from __future__ import absolute_import, division, print_function # from abc import ABCMeta, abstractmethod import copy import warnings import numpy as np -import scipy.stats +import scipy.stats as st from scipy import interpolate, linalg, special from numpy import sqrt, atleast_2d, meshgrid from numpy.fft import fftn, ifftn @@ -64,12 +64,15 @@ class _KDE(object): self.xmax = xmax self.kernel = kernel if kernel else Kernel('gauss') + self.args = None + @property def inc(self): return self._inc @inc.setter def inc(self, inc): + # pylint: disable=attribute-defined-outside-init self._inc = inc @property @@ -78,6 +81,7 @@ class _KDE(object): @dataset.setter def dataset(self, data): + # pylint: disable=attribute-defined-outside-init self._dataset = atleast_2d(data) @property @@ -103,6 +107,7 @@ class _KDE(object): def xmin(self, xmin): if xmin is None: xmin = self.dataset.min(axis=-1) - 2 * self.sigma + # pylint: disable=attribute-defined-outside-init self._xmin = self._check_xmin(xmin*np.ones(self.d)) def _check_xmin(self, xmin): @@ -116,7 +121,7 @@ class _KDE(object): def xmax(self, xmax): if xmax is None: xmax = self.dataset.max(axis=-1) + 2 * self.sigma - + # pylint: disable=attribute-defined-outside-init self._xmax = self._check_xmax(xmax * np.ones(self.d)) def _check_xmax(self, xmax): @@ -174,7 +179,7 @@ class _KDE(object): c_levels = qlevels(wdata.data, p=p_levels) wdata.clevels = c_levels wdata.plevels = p_levels - except Exception as e: + except ValueError as e: msg = "Could not calculate contour levels!. ({})".format(str(e)) warnings.warn(msg) @@ -459,7 +464,7 @@ class TKDE(_KDE): f = self._scale_pdf(tf, points) return f - def _eval_points(self, points): + def _eval_points(self, points, **kwds): """Evaluate the estimated pdf on a set of points. Parameters @@ -633,6 +638,7 @@ class KDE(_KDE): if h is None: h = self.kernel.get_smoothing(self.dataset) h = self._check_hs(h) + # pylint: disable=attribute-defined-outside-init self._inv_hs, deth = self._invert_hs(h) self._norm_factor = deth * self.n self._hs = h @@ -649,6 +655,7 @@ class KDE(_KDE): L1 = 10 inc = max(48, (L1 * xyzrange / (tau * self.hs)).max()) inc = 2 ** nextpow2(inc) + # pylint: disable=attribute-defined-outside-init self._inc = inc @property @@ -657,6 +664,7 @@ class KDE(_KDE): @alpha.setter def alpha(self, alpha): + # pylint: disable=attribute-defined-outside-init self._alpha = alpha self._lambda = np.ones(self.n) if alpha > 0: @@ -881,6 +889,8 @@ class KRegression(object): self.y = np.atleast_1d(y) self.p = p + self._grdfun = None + def eval_grid_fast(self, *args, **kwds): self._grdfun = self.tkde.eval_grid_fast return self.tkde.eval_grid_fun(self._eval_gridfun, *args, **kwds) @@ -941,6 +951,7 @@ class BKRegression(object): hs1 = self._get_max_smoothing('hste')[0] hs2 = self._get_max_smoothing('hos')[0] hs_e = sqrt(hs1 * hs2) + # pylint: disable=attribute-defined-outside-init self._hs_e = hs_e def _set_smoothing(self, hs): @@ -997,7 +1008,6 @@ class BKRegression(object): # Jeffreys intervall a=b=0.5 # st.beta.isf(alpha/2, y+a, n-y+b) y = n*p, n-y = n*(1-p) a, b = self.a, self.b - st = scipy.stats pup = np.where(p == 1, 1, st.beta.isf(alpha / 2, n * p + a, n * (1 - p) + b)) plo = np.where(p == 0, 0, diff --git a/wafo/kdetools/kernels.py b/wafo/kdetools/kernels.py index 40c42cc..0127f84 100644 --- a/wafo/kdetools/kernels.py +++ b/wafo/kdetools/kernels.py @@ -3,7 +3,7 @@ Created on 15. des. 2016 @author: pab ''' -from __future__ import division +from __future__ import absolute_import, division, print_function from abc import ABCMeta, abstractmethod import warnings import numpy as np @@ -16,6 +16,7 @@ from wafo.misc import tranproc # , trangood from wafo.kdetools.gridding import gridcount from wafo.dctpack import dct from wafo.testing import test_docstrings +from six import with_metaclass __all__ = ['Kernel', 'sphere_volume', 'qlevels', 'iqrange', 'percentile'] @@ -260,8 +261,7 @@ def sphere_volume(d, r=1.0): return (r ** d) * 2.0 * pi ** (d / 2.0) / (d * gamma(d / 2.0)) -class _Kernel(object): - __metaclass__ = ABCMeta +class _Kernel(with_metaclass(ABCMeta)): def __init__(self, r=1.0, stats=None, name=''): self.r = r # radius of effective support of kernel @@ -907,14 +907,16 @@ class Kernel(object): x = np.linspace(0, 0.1, 150) ai = x[0] + bi = x[1] f0 = fixed_point(ai, N, I, a2) - for bi in x[1:]: + for xi in x[1:]: + bi = xi f1 = fixed_point(bi, N, I, a2) if f1 * f0 <= 0: # print('ai = %g, bi = %g' % (ai,bi)) break else: - ai = bi + ai = xi # use fzero to solve the equation t=zeta*gamma^[5](t) try: diff --git a/wafo/kdetools/tests/conftest.py b/wafo/kdetools/tests/conftest.py index 5c8859b..429a459 100644 --- a/wafo/kdetools/tests/conftest.py +++ b/wafo/kdetools/tests/conftest.py @@ -1,12 +1,11 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- """ - Dummy conftest.py for wafo. + Dummy conftest.py for kdetools. If you don't know what this is for, just leave it empty. Read more about conftest.py under: https://pytest.org/latest/plugins.html """ from __future__ import print_function, absolute_import, division - +# pylint: disable=unused-import import pytest # @UnusedImport diff --git a/wafo/kdetools/tests/test_gridding.py b/wafo/kdetools/tests/test_gridding.py index b4fa4bf..4a4e92d 100644 --- a/wafo/kdetools/tests/test_gridding.py +++ b/wafo/kdetools/tests/test_gridding.py @@ -3,7 +3,7 @@ Created on 23. des. 2016 @author: pab ''' -from __future__ import division +from __future__ import absolute_import, division, print_function import unittest import numpy as np from numpy.testing import assert_allclose diff --git a/wafo/kdetools/tests/test_kdetools.py b/wafo/kdetools/tests/test_kdetools.py index 78ed8f1..a6b9224 100644 --- a/wafo/kdetools/tests/test_kdetools.py +++ b/wafo/kdetools/tests/test_kdetools.py @@ -3,7 +3,7 @@ Created on 20. nov. 2010 @author: pab ''' -from __future__ import division +from __future__ import absolute_import, division, print_function import unittest import numpy as np from numpy.testing import assert_allclose @@ -231,7 +231,8 @@ class TestRegression(unittest.TestCase): 0.0317357805015679, -0.0736187558312158, 0.04791463883941161, 0.0660021138871709, -0.1049359954387588, 0.0034961490852392463] # print(ei.tolist()) - y0 = 2*np.exp(-x**2/(2*0.3**2))+3*np.exp(-(x-1)**2/(2*0.7**2)) + y0 = 2 * np.exp(-x**2 / (2 * 0.3**2)) + 3 * \ + np.exp(-(x - 1)**2 / (2 * 0.7**2)) y = y0 + ei kreg = wk.KRegression(x, y) f = kreg(output='plotobj', title='Kernel regression', plotflag=1) diff --git a/wafo/kdetools/tests/test_kernels.py b/wafo/kdetools/tests/test_kernels.py index e771d94..17ee682 100644 --- a/wafo/kdetools/tests/test_kernels.py +++ b/wafo/kdetools/tests/test_kernels.py @@ -3,7 +3,7 @@ Created on 23. des. 2016 @author: pab ''' -from __future__ import division +from __future__ import absolute_import, division, print_function import unittest import numpy as np from numpy.testing import assert_allclose diff --git a/wafo/misc.py b/wafo/misc.py index 470e345..c7c4cdc 100644 --- a/wafo/misc.py +++ b/wafo/misc.py @@ -1,7 +1,7 @@ ''' Misc ''' -from __future__ import absolute_import, division +from __future__ import absolute_import, division, print_function import sys from wafo import numba_misc import fractions @@ -37,14 +37,22 @@ __all__ = ['now', 'spaceline', 'narg_smallest', 'args_flat', 'is_numlike', 'findpeaks', 'findrfc', 'rfcfilter', 'findtp', 'findtc', 'findoutliers', 'common_shape', 'argsreduce', 'stirlerr', 'getshipchar', 'dea3', - 'betaloge', 'gravity', 'nextpow2', 'discretize', 'polar2cart', - 'cart2polar', 'meshgrid', 'ndgrid', 'trangood', 'tranproc', - 'plot_histgrm', 'num2pistr', 'test_docstrings', 'lazywhere', - 'lazyselect', + 'betaloge', 'gravity', 'nextpow2', 'discretize', + 'polar2cart', 'cart2polar', 'pol2cart', 'cart2pol', + 'meshgrid', 'ndgrid', 'trangood', 'tranproc', + 'plot_histgrm', 'num2pistr', 'test_docstrings', + 'lazywhere', 'lazyselect', 'piecewise', 'valarray', 'check_random_state'] +def xor(a, b): + """ + Return True only when inputs differ. + """ + return a ^ b + + def check_random_state(seed): """Turn seed into a np.random.RandomState instance @@ -87,7 +95,7 @@ def valarray(shape, value=np.NaN, typecode=None): return out -def piecewise(condlist, funclist, xi=None, fill_value=0.0, args=(), **kw): +def piecewise(condlist, funclist, xi=None, fillvalue=0.0, args=(), **kw): """ Evaluate a piecewise-defined function. @@ -151,7 +159,7 @@ def piecewise(condlist, funclist, xi=None, fill_value=0.0, args=(), **kw): |funclist[0](x0[condlist[0]],x1[condlist[0]],...,xn[condlist[0]]) out = |funclist[1](x0[condlist[1]],x1[condlist[1]],...,xn[condlist[1]]) |... - |funclist[n2](x0[condlist[n2]],x1[condlist[n2]],...,xn[condlist[n2]]) + |funclist[n2](x0[condlist[n2]], x1[condlist[n2]],..,xn[condlist[n2]]) |-- Examples @@ -159,8 +167,9 @@ def piecewise(condlist, funclist, xi=None, fill_value=0.0, args=(), **kw): Define the sigma function, which is -1 for ``x < 0`` and +1 for ``x >= 0``. >>> x = np.linspace(-2.5, 2.5, 6) - >>> piecewise([x < 0, x >= 0], [-1, 1]) - array([-1., -1., -1., 1., 1., 1.]) + >>> np.allclose(piecewise([x < 0, x >= 0], [-1, 1]), + ... [-1, -1, -1, 1, 1, 1]) + True Define the absolute value, which is ``-x`` for ``x <0`` and ``x`` for ``x >= 0``. @@ -185,8 +194,7 @@ def piecewise(condlist, funclist, xi=None, fill_value=0.0, args=(), **kw): def check_shapes(condlist, funclist): nc, nf = len(condlist), len(funclist) - if nc not in [nf - 1, nf]: - raise ValueError("function list and condition list" + + _assert(nc in [nf - 1, nf], "function list and condition list" " must be the same length") check_shapes(condlist, funclist) @@ -197,21 +205,20 @@ def piecewise(condlist, funclist, xi=None, fill_value=0.0, args=(), **kw): if xi is None: arrays = () dtype = np.result_type(*funclist) - shape = condlist[0].shape else: if not isinstance(xi, tuple): xi = (xi,) arrays = np.broadcast_arrays(*xi) dtype = np.result_type(*arrays) - shape = arrays[0].shape - out = valarray(shape, fill_value, dtype) + out = valarray(condlist[0].shape, fillvalue, dtype) for cond, func in zip(condlist, funclist): - if isinstance(func, Callable): - temp = tuple(np.extract(cond, arr) for arr in arrays) + args - np.place(out, cond, func(*temp, **kw)) - else: # func is a scalar value or a list - np.putmask(out, cond, func) + if cond.any(): + if isinstance(func, collections.Callable): + temp = tuple(np.extract(cond, arr) for arr in arrays) + args + np.place(out, cond, func(*temp, **kw)) + else: # func is a scalar value or a array + np.putmask(out, cond, func) return out @@ -223,12 +230,12 @@ def lazywhere(cond, arrays, f, fillvalue=None, f2=None): >>> a, b = np.array([1, 2, 3, 4]), np.array([5, 6, 7, 8]) >>> def f(a, b): ... return a*b - >>> def f2(a, b): - ... return np.ones(np.shape(a))*np.ones(np.shape(b)) >>> lazywhere(a > 2, (a, b), f, np.nan) array([ nan, nan, 21., 32.]) + >>> def f2(a, b): + ... return (a*b)**2 >>> lazywhere(a > 2, (a, b), f, f2=f2) - array([ 1., 1., 21., 32.]) + array([ 25., 144., 21., 32.]) Notice it assumes that all `arrays` are of the same shape, or can be broadcasted together. @@ -293,6 +300,10 @@ def lazyselect(condlist, choicelist, arrays, default=0): def rotation_matrix(heading, pitch, roll): ''' + Parameters + ---------- + heading, pitch, roll : real scalars + defining heading, pitch and roll in degrees. Examples -------- @@ -681,7 +692,7 @@ class Bunch(object): self.__dict__.update(kwargs) -def printf(format_, *args): +def printf(format_, *args): # @ReservedAssignment sys.stdout.write(format_ % args) @@ -748,6 +759,7 @@ def detrendma(x, L): Examples -------- + >>> import matplotlib.pyplot as plt >>> import numpy as np >>> import wafo.misc as wm >>> exp = np.exp; cos = np.cos; randn = np.random.randn @@ -767,7 +779,6 @@ def detrendma(x, L): >>> np.allclose(wm.detrendma(x2, L=1), [-1, 0, 0, 0, 1]) True - import pylab as plt h = plt.plot(x, y, x, y0, 'r', x, exp(x), 'k', x, tr, 'm') plt.close('all') @@ -776,7 +787,7 @@ def detrendma(x, L): Reconstruct """ _assert(0 < L, 'L must be positive') - _assert(L == round(L), 'L must be an integer') + _assert(L == np.round(L), 'L must be an integer') x1 = np.atleast_1d(x) if x1.shape[0] == 1: @@ -820,7 +831,7 @@ def ecross(t, f, ind, v=0): Example ------- - >>> from matplotlib import pylab as plt + >>> from matplotlib import pyplot as plt >>> import wafo.misc as wm >>> ones = np.ones >>> t = np.linspace(0,7*np.pi,250) @@ -857,12 +868,6 @@ def _findcross(xn, method='clib'): return numba_misc.findcross(xn) -def xor(a, b): - """ - Return True only when inputs differ. - """ - return a ^ b - def findcross(x, v=0.0, kind=None, method='clib'): ''' @@ -891,7 +896,7 @@ def findcross(x, v=0.0, kind=None, method='clib'): Example ------- - >>> from matplotlib import pylab as plt + >>> from matplotlib import pyplot as plt >>> import wafo.misc as wm >>> ones = np.ones >>> np.allclose(findcross([0, 1, -1, 1], 0), [0, 1, 2]) @@ -935,19 +940,20 @@ def findcross(x, v=0.0, kind=None, method='clib'): t_0 = int(xn[ind[0] + 1] < 0) ind = ind[t_0::2] elif kind in ('dw', 'uw', 'tw', 'cw'): - # make sure the first is a level v down-crossing + # make sure that the first is a level v down-crossing # if kind=='dw' or kind=='tw' - # or make sure the first is a level v up-crossing + # or that the first is a level v up-crossing # if kind=='uw' or kind=='cw' first_is_down_crossing = int(xn[ind[0]] > xn[ind[0] + 1]) if xor(first_is_down_crossing, kind in ('dw', 'tw')): ind = ind[1::] + n_c = ind.size # number of level v crossings # make sure the number of troughs and crests are according to the - # wavedef, i.e., make sure length(ind) is odd if kind is dw or uw - # and even if kind is tw or cw - is_odd = mod(ind.size, 2) + # wavedef, i.e., make sure length(ind) is odd if dw or uw + # and even if tw or cw + is_odd = mod(n_c, 2) if xor(is_odd, kind in ('dw', 'uw')): ind = ind[:-1] else: @@ -971,7 +977,7 @@ def findextrema(x): Examples -------- >>> import numpy as np - >>> import pylab as plt + >>> import matplotlib.pyplot as plt >>> import wafo.misc as wm >>> t = np.linspace(0,7*np.pi,250) >>> x = np.sin(t) @@ -1268,7 +1274,7 @@ def findtp(x, h=0.0, kind=None): Example: -------- - >>> import pylab as plt + >>> import matplotlib.pyplot as plt >>> import wafo.misc as wm >>> t = np.linspace(0,30,500).reshape((-1,1)) >>> x = np.hstack((t, np.cos(t) + 0.3 * np.sin(5*t))) @@ -1370,7 +1376,7 @@ def findtc(x_in, v=None, kind=None): Example: -------- - >>> import pylab as plt + >>> import matplotlib.pyplot as plt >>> import wafo.misc as wm >>> t = np.linspace(0,30,500).reshape((-1,1)) >>> x = np.hstack((t, np.cos(t))) @@ -1575,8 +1581,7 @@ def findoutliers(x, zcrit=0.0, dcrit=None, ddcrit=None, verbose=False): def common_shape(*args, ** kwds): - ''' - Return the common shape of a sequence of arrays + """Return the common shape of a sequence of arrays. Parameters ----------- @@ -1610,7 +1615,8 @@ def common_shape(*args, ** kwds): See also -------- broadcast, broadcast_arrays - ''' + + """ shape = kwds.get('shape') x0 = 1 if shape is None else np.ones(shape) return tuple(np.broadcast(x0, *args).shape) @@ -1946,9 +1952,9 @@ def gravity(phi=45): >>> import wafo.misc as wm >>> import numpy as np >>> phi = np.linspace(0,45,5) - >>> np.abs(wm.gravity(phi)-np.array([ 9.78049 , 9.78245014, 9.78803583, - ... 9.79640552, 9.80629387]))<1.e-7 - array([ True, True, True, True, True], dtype=bool) + >>> np.allclose(wm.gravity(phi), + ... [ 9.78049 , 9.78245014, 9.78803583, 9.79640552, 9.80629387]) + True See also -------- @@ -2018,15 +2024,13 @@ def discretize(fun, a, b, tol=0.005, n=5, method='linear'): ------- >>> import wafo.misc as wm >>> import numpy as np - >>> import pylab as plt + >>> import matplotlib.pyplot as plt >>> x,y = wm.discretize(np.cos, 0, np.pi) - >>> np.allclose(x[:5], - ... [ 0. , 0.19634954, 0.39269908, 0.58904862, 0.78539816]) + >>> np.allclose(x[:5], [0., 0.19634954, 0.39269908, 0.58904862, 0.78539816]) True >>> xa,ya = wm.discretize(np.cos, 0, np.pi, method='adaptive') - >>> np.allclose(xa[:5], - ... [ 0. , 0.19634954, 0.39269908, 0.58904862, 0.78539816]) + >>> np.allclose(xa[:5], [0., 0.19634954, 0.39269908, 0.58904862, 0.78539816]) True @@ -2306,11 +2310,11 @@ def tranproc(x, f, x0, *xi): Example -------- Derivative of g and the transformed Gaussian model. - >>> import pylab as plt + >>> import matplotlib.pyplot as plt >>> import wafo.misc as wm >>> import wafo.transform.models as wtm >>> tr = wtm.TrHermite() - >>> x = linspace(-5,5,501) + >>> x = np.linspace(-5, 5, 501) >>> g = tr(x) >>> gder = wm.tranproc(x, g, x, ones(g.shape[0])) >>> np.allclose(gder[1][:5], @@ -2542,7 +2546,7 @@ def plot_histgrm(data, bins=None, range=None, # @ReservedAssignment Example ------- - >>> import pylab as plt + >>> import matplotlib.pyplot as plt >>> import wafo.misc as wm >>> import wafo.stats as ws >>> R = ws.weibull_min.rvs(2,loc=0,scale=2, size=100) @@ -2551,10 +2555,11 @@ def plot_histgrm(data, bins=None, range=None, # @ReservedAssignment >>> len(bins) 13 - h0 = wm.plot_histgrm(R, bins, normed=True) - x = np.linspace(-3,16,200) + >>> x = np.linspace(-3,16,200) + >>> pdf = ws.weibull_min.pdf(x,2,0,2) - h1 = plt.plot(x,ws.weibull_min.pdf(x,2,0,2),'r') + h0 = wm.plot_histgrm(R, 20, normed=True) + h1 = plt.plot(x, pdf,'r') plt.close('all') See also @@ -2657,10 +2662,11 @@ def fourier(data, t=None, period=None, m=None, n=None, method='trapz'): >>> t = np.linspace(0,4*T) >>> x = np.sin(t) >>> a, b = wm.fourier(x, t, period=T, m=5) - >>> np.abs(a.ravel())<1e-12 - array([ True, True, True, True, True], dtype=bool) - >>> np.abs(b.ravel()-np.array([ 0., 4., 0., 0., 0.]))<1e-12 - array([ True, True, True, True, True], dtype=bool) + >>> np.allclose(a, 0) + True + >>> np.allclose(b.ravel(), + ... [ 0., 4., 0., 0., 0.]) + True See also -------- diff --git a/wafo/polynomial.py b/wafo/polynomial.py index 7f008f0..035a8c0 100644 --- a/wafo/polynomial.py +++ b/wafo/polynomial.py @@ -17,7 +17,7 @@ # Licence: LGPL # ------------------------------------------------------------------------ # !/usr/bin/env python -from __future__ import absolute_import +from __future__ import absolute_import, division, print_function import warnings # @UnusedImport from functools import reduce from numpy.polynomial import polyutils as pu @@ -374,14 +374,17 @@ def ortho2poly(p): >>> x = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0]) >>> y = np.array([0.0, 0.8, 0.9, 0.1, -0.8, -1.0]) >>> p = wp.orthofit(x, y, 3) - >>> p - array([[ 0. , -0.30285714, -0.16071429, 0.08703704], - [ 0. , 2.5 , 2.5 , 2.5 ], - [ 0. , 0. , 2.91666667, 2.13333333]]) - >>> wp.ortho2poly(p) - array([ 0.08703704, -0.81349206, 1.69312169, -0.03968254]) - >>> wp.polyfit(x, y, 3) - array([ 0.08703704, -0.81349206, 1.69312169, -0.03968254]) + + >>> np.allclose(p,[[ 0. , -0.30285714, -0.16071429, 0.08703704], + ... [ 0. , 2.5 , 2.5 , 2.5 ], + ... [ 0. , 0. , 2.91666667, 2.13333333]]) + True + >>> np.allclose(wp.ortho2poly(p), + ... [ 0.08703704, -0.81349206, 1.69312169, -0.03968254]) + True + >>> np.allclose(np.polyfit(x, y, 3), + ... [ 0.08703704, -0.81349206, 1.69312169, -0.03968254]) + True References ----------