From: W. Trevor King Date: Sat, 7 Aug 2010 14:21:34 +0000 (-0400) Subject: Added point-click status notification to gui.panel.plot. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=ef725eb27006d7506d78fe843abeedc219294c61;p=hooke.git Added point-click status notification to gui.panel.plot. Now clicking on points displays their x/y value as well as the index of the nearest x point for the various displayed data blocks. This allowed me to adjust the bounds of the testing WLC fit in hooke.ui.gui to more appropriate values, but these commands will eventually be removed once I get through the rough development phase. --- diff --git a/hooke/ui/gui/__init__.py b/hooke/ui/gui/__init__.py index 3bc29d5..fecc90d 100644 --- a/hooke/ui/gui/__init__.py +++ b/hooke/ui/gui/__init__.py @@ -125,7 +125,7 @@ class HookeFrame (wx.Frame): ) self.execute_command( command=self._command_by_name('polymer fit'), - args={'block':1, 'bounds':[400, 1000]}, + args={'block':1, 'bounds':[918, 1103]}, ) return # TODO: cleanup self.playlists = self._c['playlist'].Playlists @@ -201,6 +201,7 @@ class HookeFrame (wx.Frame): # style=wx.NO_BORDER|wx.TE_MULTILINE), 'right'), (panel.PANELS['plot']( callbacks={ + '_set_status_text': self._on_plot_status_text, }, parent=self, style=wx.WANTS_CHARS|wx.NO_BORDER, @@ -771,6 +772,14 @@ class HookeFrame (wx.Frame): + # Plot panel interface + + def _on_plot_status_text(self, _class, method, text): + if 'status bar' in self._c: + self._c['status bar'].set_plot_text(text) + + + # Navbar interface def _next_curve(self, *args): @@ -912,6 +921,8 @@ class HookeFrame (wx.Frame): style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) dialog.CenterOnScreen() dialog.ShowModal() + if dialog.canceled == True: + return names = [options[i] for i in dialog.selected] dialog.Destroy() self._delete_perspectives( diff --git a/hooke/ui/gui/dialog/selection.py b/hooke/ui/gui/dialog/selection.py index ff7fbb7..1ef0c76 100644 --- a/hooke/ui/gui/dialog/selection.py +++ b/hooke/ui/gui/dialog/selection.py @@ -49,6 +49,7 @@ class Selection (wx.Dialog): callbacks = {} self._callbacks = callbacks self._selection_style = selection_style + self.canceled = False self._c = { 'text': wx.StaticText( @@ -97,6 +98,7 @@ class Selection (wx.Dialog): def cancel(self, event): """Close the dialog. """ + self.canceled = True self.EndModal(wx.ID_CANCEL) def button(self, event): diff --git a/hooke/ui/gui/panel/plot.py b/hooke/ui/gui/panel/plot.py index 030fce7..66cc64d 100644 --- a/hooke/ui/gui/panel/plot.py +++ b/hooke/ui/gui/panel/plot.py @@ -36,6 +36,7 @@ from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas from matplotlib.backends.backend_wx import NavigationToolbar2Wx as NavToolbar from matplotlib.figure import Figure from matplotlib.ticker import Formatter, ScalarFormatter +import numpy import wx from ....util.callback import callback, in_callback @@ -104,8 +105,11 @@ class PlotPanel (Panel, wx.Panel): self.display_coordinates = False self.style = 'line' self._curve = None + self._config = {} self._x_column = None self._y_columns = [] # TODO: select right/left scales? + self._x_unit = '' + self._y_unit = '' super(PlotPanel, self).__init__( name='plot', callbacks=callbacks, **kwargs) self._c = {} @@ -173,17 +177,32 @@ class PlotPanel (Panel, wx.Panel): self._c['figure'].set_edgecolor(col) self._c['canvas'].SetBackgroundColour(wx.Colour(*rgbtuple)) - #def SetStatusText(self, text, field=1): - # self.Parent.Parent.statusbar.SetStatusText(text, field) + def _set_status_text(self, text): + in_callback(self, text) def _on_size(self, event): event.Skip() wx.CallAfter(self._resize_canvas) def _on_click(self, event): - #self.SetStatusText(str(event.xdata)) - #print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(event.button, event.x, event.y, event.xdata, event.ydata) - pass + if self._curve == None: + return + d = self._config.get('plot decimals', 2) + x,y = (event.xdata, event.ydata) + xt = ppSI(value=x, unit=self._x_unit, decimals=d) + yt = ppSI(value=y, unit=self._y_unit, decimals=d) + point_indexes = [] + for data in self._curve.data: + try: + x_col = data.info['columns'].index(self._x_column) + except ValueError: + continue # data is missing a required column + index = numpy.absolute(data[:,x_col]-x).argmin() + point_indexes.append((data.info['name'], index)) + self._set_status_text( + '(%s, %s) %s' + % (xt, yt, + ', '.join(['%s: %d' % (n,i) for n,i in point_indexes]))) def _on_enter_axes(self, event): self.display_coordinates = True @@ -222,6 +241,8 @@ class PlotPanel (Panel, wx.Panel): style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) s.CenterOnScreen() s.ShowModal() + if s.canceled == True: + return self._y_columns = [self._columns[i] for i in s.selected] s.Destroy() if len(self._y_columns) == 0: @@ -276,22 +297,24 @@ class PlotPanel (Panel, wx.Panel): if config['plot SI format'] == True: d = config['plot decimals'] - x_n, x_unit = split_data_label(self._x_column) - y_n, y_unit = split_data_label(self._y_columns[0]) + x_n, self._x_unit = split_data_label(self._x_column) + y_n, self._y_unit = split_data_label(self._y_columns[0]) for y_column in self._y_columns[1:]: - y_n2, y_unit2 = split_data_label(y_column) - if y_unit2 != y_unit: + y_n, y_unit = split_data_label(y_column) + if y_unit != self._y_unit: log = logging.getLogger('hooke') log.warn('y-axes unit mismatch: %s != %s, using %s.' - % (y_unit, y_unit2, y_unit)) - fx = HookeFormatter(decimals=d, unit=x_unit) + % (self._y_unit, y_unit, self._y_unit)) + fx = HookeFormatter(decimals=d, unit=self._x_unit) axes.xaxis.set_major_formatter(fx) - fy = HookeFormatter(decimals=d, unit=y_unit) + fy = HookeFormatter(decimals=d, unit=self._y_unit) axes.yaxis.set_major_formatter(fy) axes.set_xlabel(x_n) if len(self._y_columns) == 1: axes.set_ylabel(y_n) else: + self._x_unit = '' + self._y_unit = '' axes.set_xlabel(self._x_column) if len(self._y_columns) == 1: axes.set_ylabel(self._y_columns[0]) diff --git a/hooke/ui/gui/statusbar.py b/hooke/ui/gui/statusbar.py index dcd1ac3..7eb33eb 100644 --- a/hooke/ui/gui/statusbar.py +++ b/hooke/ui/gui/statusbar.py @@ -27,6 +27,7 @@ from ... import version class StatusBar (wx.StatusBar): def __init__(self, *args, **kwargs): super(StatusBar, self).__init__(*args, **kwargs) + self.SetFieldsCount(2) self.SetStatusWidths([-2, -3]) self.SetStatusText('Ready', 0) self.SetStatusText(u'Welcome to Hooke (version %s)' % version(), 1) @@ -37,6 +38,9 @@ class StatusBar (wx.StatusBar): def set_curve(self, curve): pass + def set_plot_text(self, text): + self.SetStatusText(text, 1) + def _playlist_status(self, playlist): fields = [ playlist.name,