From: W. Trevor King Date: Sat, 7 Aug 2010 12:59:05 +0000 (-0400) Subject: Add ability to select multiple y columns to gui.panel.plot X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=533bfff9ccca2270f09aac17226ee70ee1277149;p=hooke.git Add ability to select multiple y columns to gui.panel.plot --- diff --git a/hooke/ui/gui/panel/plot.py b/hooke/ui/gui/panel/plot.py index 2eb9eab..030fce7 100644 --- a/hooke/ui/gui/panel/plot.py +++ b/hooke/ui/gui/panel/plot.py @@ -28,6 +28,8 @@ Originally based on `this example`_. http://matplotlib.sourceforge.net/examples/user_interfaces/embedding_in_wx2.html """ +import logging + import matplotlib matplotlib.use('WXAgg') # use wxpython with antigrain (agg) rendering from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas @@ -38,6 +40,7 @@ import wx from ....util.callback import callback, in_callback from ....util.si import ppSI, split_data_label +from ..dialog.selection import Selection from . import Panel @@ -102,7 +105,7 @@ class PlotPanel (Panel, wx.Panel): self.style = 'line' self._curve = None self._x_column = None - self._y_column = None # TODO: _y_columns (allow multiple, simultaneous y axes (rescaled?)) + self._y_columns = [] # TODO: select right/left scales? super(PlotPanel, self).__init__( name='plot', callbacks=callbacks, **kwargs) self._c = {} @@ -134,11 +137,11 @@ class PlotPanel (Panel, wx.Panel): self._c['x column'].SetToolTip(wx.ToolTip('x column')) self._c['toolbar'].AddControl(self._c['x column']) self._c['x column'].Bind(wx.EVT_CHOICE, self._on_x_column) - self._c['y column'] = wx.Choice( - parent=self._c['toolbar'], choices=[]) + self._c['y column'] = wx.Button( + parent=self._c['toolbar'], label='y column(s)') self._c['y column'].SetToolTip(wx.ToolTip('y column')) self._c['toolbar'].AddControl(self._c['y column']) - self._c['y column'].Bind(wx.EVT_CHOICE, self._on_y_column) + self._c['y column'].Bind(wx.EVT_BUTTON, self._on_y_column) self._c['toolbar'].Realize() # call after putting items in the toolbar if wx.Platform == '__WXMAC__': @@ -206,7 +209,23 @@ class PlotPanel (Panel, wx.Panel): self.update() def _on_y_column(self, event): - self._y_column = self._c['y column'].GetStringSelection() + if not hasattr(self, '_columns') or len(self._columns) == 0: + self._y_columns = [] + return + s = Selection( + options=self._columns, + message='Select visible y column(s).', + button_id=wx.ID_OK, + selection_style='multiple', + parent=self, + title='Select y column(s)', + style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) + s.CenterOnScreen() + s.ShowModal() + self._y_columns = [self._columns[i] for i in s.selected] + s.Destroy() + if len(self._y_columns) == 0: + self._y_columns = self._columns[-1:] self.update() def _resize_canvas(self): @@ -234,18 +253,14 @@ class PlotPanel (Panel, wx.Panel): self._columns = sorted(columns) if self._x_column not in self._columns: self._x_column = self._columns[0] - if self._y_column not in self._columns: - self._y_column = self._columns[-1] + self._y_columns = [y for y in self._y_columns if y in self._columns] + if len(self._y_columns) == 0: + self._y_columns = self._columns[-1:] if 'x column' in self._c: for i in range(self._c['x column'].GetCount()): self._c['x column'].Delete(0) self._c['x column'].AppendItems(self._columns) self._c['x column'].SetStringSelection(self._x_column) - if 'y column' in self._c: - for i in range(self._c['y column'].GetCount()): - self._c['y column'].Delete(0) - self._c['y column'].AppendItems(self._columns) - self._c['y column'].SetStringSelection(self._y_column) self.update(config=config) def update(self, config=None): @@ -262,27 +277,36 @@ 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_column) + y_n, 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: + 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) axes.xaxis.set_major_formatter(fx) fy = HookeFormatter(decimals=d, unit=y_unit) axes.yaxis.set_major_formatter(fy) axes.set_xlabel(x_n) - axes.set_ylabel(y_n) + if len(self._y_columns) == 1: + axes.set_ylabel(y_n) else: axes.set_xlabel(self._x_column) - axes.set_ylabel(self._y_column) + if len(self._y_columns) == 1: + axes.set_ylabel(self._y_columns[0]) self._c['figure'].hold(True) for i,data in enumerate(self._curve.data): - try: - x_col = data.info['columns'].index(self._x_column) - y_col = data.info['columns'].index(self._y_column) - except ValueError: - continue # data is missing a required column - axes.plot(data[:,x_col], data[:,y_col], - '.', - label=data.info['name']) - if config['plot legend'] == 'True': # HACK: config should convert + for y_column in self._y_columns: + try: + x_col = data.info['columns'].index(self._x_column) + y_col = data.info['columns'].index(y_column) + except ValueError: + continue # data is missing a required column + axes.plot(data[:,x_col], data[:,y_col], + '.', + label=('%s, %s' % (data.info['name'], y_column))) + if config['plot legend'] == True: axes.legend(loc='best') self._c['canvas'].draw()