Example #1
0
    def __init__(self,
                 parent,
                 win_id=wx.ID_ANY,
                 value=wx.EmptyString,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 choices=[],
                 style=0,
                 validator=wx.DefaultValidator,
                 name=wx.ComboBoxNameStr,
                 monospace=False,
                 defaultValue=wx.EmptyString,
                 required=False,
                 outLabel=None):

        OwnerDrawnComboBox.__init__(self, parent, win_id, value, pos, size,
                                    choices, style, validator, name)
        InputField.__init__(self, defaultValue, required, outLabel)

        if wx.MAJOR_VERSION < 3:
            self.clr_disabled = self.GetBackgroundColour()
            self.clr_enabled = self.GetTextCtrl().GetBackgroundColour()

        if monospace:
            self.TextCtrl.SetFont(MONOSPACED_MD)
            # FIXME: This doesn't work (use monospace in popup list)
            self.PopupControl.GetControl().SetFont(MONOSPACED_MD)
Example #2
0
    def __init__(self, parent, table_a, table_b, col_a=None, col_b=None, allow_delete=True, **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)
        self.table_a = table_a
        self.table_b = table_b
        self.aChoice = ComboBox(self, choices=db.GetColumnNames(table_a), 
                                size=(100,-1), style=wx.CB_READONLY)
        self.bChoice = ComboBox(self, choices=db.GetColumnNames(table_b), 
                                size=(100,-1), style=wx.CB_READONLY)
        if col_a in self.aChoice.Strings:
            self.aChoice.Select(self.aChoice.Strings.index(col_a))
        if col_b in self.bChoice.Strings:
            self.bChoice.Select(self.bChoice.Strings.index(col_b))

        if allow_delete:
            self.x_btn = wx.Button(self, -1, 'x', size=(30,-1))

        self.Sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.Sizer.Add(wx.StaticText(self, -1, table_a+'.'), 0, wx.TOP, 4)
        self.Sizer.Add(self.aChoice, 1, wx.EXPAND)
        self.Sizer.AddSpacer((10,-1))
        self.Sizer.Add(wx.StaticText(self, -1, '<=>'), 0, wx.TOP, 4)
        self.Sizer.AddSpacer((10,-1))
        self.Sizer.Add(wx.StaticText(self, -1, table_b+'.'), 0, wx.TOP, 4)
        self.Sizer.Add(self.bChoice, 1, wx.EXPAND)
        if allow_delete:
            self.Sizer.AddSpacer((10,-1))
            self.Sizer.Add(self.x_btn)
            self.x_btn.Bind(wx.EVT_BUTTON, self.GrandParent.on_remove_panel)
Example #3
0
    def __init__(self, parent, figpanel, **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)
        
        # the panel to draw charts on
        self.SetBackgroundColour('white') # color for the background of panel
        self.figpanel = figpanel
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        
        self.x_columns = [] # column names to plot if selecting multiple columns

        self.table_choice = ui.TableComboBox(self, -1, style=wx.CB_READONLY)
        self.x_choice = ComboBox(self, -1, size=(200,-1))
        self.x_multiple = wx.Button(self, -1, 'select multiple')
        self.group_choice = ComboBox(self, -1, choices=[NO_GROUP]+p._groups_ordered, style=wx.CB_READONLY)
        self.group_choice.Select(0)
        self.filter_choice = ui.FilterComboBox(self, style=wx.CB_READONLY)
        self.filter_choice.Select(0)
        self.update_chart_btn = wx.Button(self, -1, "Update Chart")
        
        self.update_column_fields()
        
        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "table:"), 0, wx.TOP, 4)
        sz.AddSpacer((3,-1))
        sz.Add(self.table_choice, 1, wx.EXPAND)
        sz.AddSpacer((3,-1))
        sz.Add(wx.StaticText(self, -1, "measurement:"), 0, wx.TOP, 4)
        sz.AddSpacer((3,-1))
        sz.Add(self.x_choice, 2, wx.EXPAND)
        sz.AddSpacer((3,-1))
        sz.Add(self.x_multiple, 0, wx.EXPAND|wx.TOP, 2)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1,3))
        
        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "group x-axis by:"), 0, wx.TOP, 4)
        sz.AddSpacer((3,-1))
        sz.Add(self.group_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1,3))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "filter:"), 0, wx.TOP, 4)
        sz.AddSpacer((3,-1))
        sz.Add(self.filter_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1,3))
        
        sizer.Add(self.update_chart_btn)    
        
        wx.EVT_BUTTON(self.x_multiple, -1, self.on_select_multiple)
        wx.EVT_COMBOBOX(self.table_choice, -1, self.on_table_selected)
        wx.EVT_COMBOBOX(self.x_choice, -1, self.on_column_selected)
        wx.EVT_BUTTON(self.update_chart_btn, -1, self.update_figpanel)   
        
        self.SetSizer(sizer)
        self.Show(1)
Example #4
0
 def __init__(self, parent, id=-1, **kwargs):
     if kwargs.get('choices', None) is None:
         choices = db.get_linkable_tables()
         choices += [TableComboBox.OTHER_TABLE]
     else:
         choices = kwargs['choices']
     ComboBox.__init__(self, parent, id, choices=choices, **kwargs)
     if p.image_table:
         self.SetStringSelection(p.image_table)
     else:
         self.Select(0)
 def __init__(self, parent, id=-1, **kwargs):
     if kwargs.get('choices', None) is None:
         choices = db.get_linkable_tables()
         choices += [TableComboBox.OTHER_TABLE]
     else:
         choices = kwargs['choices']
     ComboBox.__init__(self, parent, id, choices=choices, **kwargs)
     if p.image_table:
         self.SetStringSelection(p.image_table)
     else:
         self.Select(0)
Example #6
0
    def __init__(self,
                 parent,
                 tables,
                 allow_delete=True,
                 expression=None,
                 **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)

        self.fieldSets = []
        self.tables = tables
        self.types = {}
        self.types[p.image_table] = db.GetColumnTypes(p.image_table)
        self.tableChoice = ComboBox(self,
                                    choices=self.tables,
                                    size=(150, -1),
                                    style=wx.CB_READONLY)
        self.tableChoice.Select(0)
        self.colChoice = ComboBox(self,
                                  choices=db.GetColumnNames(p.image_table),
                                  size=(150, -1),
                                  style=wx.CB_READONLY)
        self.colChoice.Select(0)
        self.comparatorChoice = ComboBox(self, size=(80, -1))
        self.update_comparator_choice()
        self.valueField = wx.ComboBox(self, -1, value='')
        if allow_delete:
            self.x_btn = wx.Button(self, -1, 'x', size=(30, -1))

##        if expression is not None:
##            self.set_expression(expression)

        colSizer = wx.BoxSizer(wx.HORIZONTAL)
        colSizer.Add(self.tableChoice, 1, wx.EXPAND)
        colSizer.AddSpacer((5, -1))
        colSizer.Add(self.colChoice, 1, wx.EXPAND)
        colSizer.AddSpacer((5, -1))
        colSizer.Add(self.comparatorChoice, 0.5, wx.EXPAND)
        colSizer.AddSpacer((5, -1))
        colSizer.Add(self.valueField, 1, wx.EXPAND)
        if allow_delete:
            colSizer.AddSpacer((5, -1))
            colSizer.Add(self.x_btn, 0, wx.EXPAND)

        self.SetSizer(colSizer)
        self.tableChoice.Bind(wx.EVT_COMBOBOX, self.on_select_table)
        self.colChoice.Bind(wx.EVT_COMBOBOX, self.on_select_col)
        if allow_delete:
            self.x_btn.Bind(wx.EVT_BUTTON, self.on_remove)
        self.Fit()
    def __init__(self, parent, fig_sco, fig_load, **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)
        self.fig_sco = fig_sco
        self.fig_load = fig_load
        sizer = wx.BoxSizer(wx.VERTICAL)

        self.method_choice = ComboBox(self,
                                      -1,
                                      choices=[SVD, TSNE],
                                      style=wx.CB_READONLY)
        self.method_choice.Select(0)
        self.update_chart_btn = wx.Button(self, -1, "Show plot")
        self.help_btn = wx.Button(self, -1, "About")

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "Method:"))
        sz.AddSpacer((5, -1))
        sz.Add(self.method_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 5))

        sz2 = wx.BoxSizer(wx.HORIZONTAL)
        sz2.Add(self.help_btn, wx.LEFT)
        sz2.AddSpacer((400, -1))
        sz2.Add(self.update_chart_btn, wx.RIGHT)

        sizer.Add(sz2, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 5))

        wx.EVT_BUTTON(self.update_chart_btn, -1, self.on_show_pressed)
        wx.EVT_BUTTON(self.help_btn, -1, self.on_show_about)

        self.SetSizer(sizer)
        self.Show(1)
Example #8
0
	def __init__(self, parent, win_id=wx.ID_ANY, value=wx.EmptyString, pos=wx.DefaultPosition,
			size=wx.DefaultSize, choices=[], style=0, validator=wx.DefaultValidator,
			name=wx.ComboBoxNameStr, monospace=False, defaultValue=wx.EmptyString,
			required=False, outLabel=None):

		OwnerDrawnComboBox.__init__(self, parent, win_id, value, pos, size, choices, style,
				validator, name)
		InputField.__init__(self, defaultValue, required, outLabel)

		if wx.MAJOR_VERSION < 3:
			self.clr_disabled = self.GetBackgroundColour()
			self.clr_enabled = self.GetTextCtrl().GetBackgroundColour()

		if monospace:
			self.TextCtrl.SetFont(MONOSPACED_MD)
			# FIXME: This doesn't work (use monospace in popup list)
			self.PopupControl.GetControl().SetFont(MONOSPACED_MD)
Example #9
0
    def __init__(self,
                 parent,
                 win_id=wx.ID_ANY,
                 value=wx.EmptyString,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 choices=[],
                 style=0,
                 validator=wx.DefaultValidator,
                 name=wx.ComboBoxNameStr):
        OwnerDrawnComboBox.__init__(self, parent, win_id, value, pos, size,
                                    choices, style, validator, name)

        self.Default = self.GetLabel()
        self.Priority = []

        if wx.MAJOR_VERSION <= 2:
            self.BGDefault = self.TextCtrl.GetBackgroundColour()
            self.BGDisabled = self.TextCtrl.GetForegroundColour()
Example #10
0
    def Enable(self, *args, **kwargs):
        return_value = OwnerDrawnComboBox.Enable(self, *args, **kwargs)

        if wx.MAJOR_VERSION < 3:
            text_area = self.GetTextCtrl()

            if self.IsEnabled():
                text_area.SetBackgroundColour(self.clr_enabled)

            else:
                text_area.SetBackgroundColour(self.clr_disabled)

        return return_value
Example #11
0
    def IsEnabled(self):
        if wx.MAJOR_VERSION > 2:
            return OwnerDrawnComboBox.IsEnabled(self)

        enabled = FieldsEnabled((
            self.TextCtrl,
            self.PopupWindow,
        ))

        # DEBUG: START
        print(u'\nDEBUG custom.combo.ComboCtrl.IsEnabled override')
        print(u'    FieldsEnabled returned "{}"'.format(enabled))
        # DEBUG: END

        return enabled
Example #12
0
    def Set(self, items):
        # Text control is cleared when options are changed
        cached_value = self.GetValue()

        if not isinstance(items, (tuple, list, dict)):
            items = (items, )

        if wx.MAJOR_VERSION > 2:
            OwnerDrawnComboBox.Set(self, items)

        else:
            self.Clear()

            for I in items:
                self.Append(I)

        if not TextIsEmpty(cached_value):
            self.SetValue(cached_value)
Example #13
0
    def __init__(self, parent, figpanel, **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)
        # the panel to draw charts on
        self.figpanel = figpanel

        sizer = wx.BoxSizer(wx.VERTICAL)

        self.x_table_choice = ui.TableComboBox(self, -1, style=wx.CB_READONLY)
        self.y_table_choice = ui.TableComboBox(self, -1, style=wx.CB_READONLY)
        self.x_choice = ComboBox(self,
                                 -1,
                                 size=(200, -1),
                                 style=wx.CB_READONLY)
        self.y_choice = ComboBox(self,
                                 -1,
                                 size=(200, -1),
                                 style=wx.CB_READONLY)
        self.gridsize_input = wx.TextCtrl(self, -1, '50')
        maps = [m for m in matplotlib.cm.datad.keys() if not m.endswith("_r")]
        maps.sort()
        self.colormap_choice = ComboBox(self,
                                        -1,
                                        choices=maps,
                                        style=wx.CB_READONLY)
        self.colormap_choice.SetSelection(maps.index('jet'))
        self.color_scale_choice = ComboBox(self,
                                           -1,
                                           choices=[LINEAR_SCALE, LOG_SCALE],
                                           style=wx.CB_READONLY)
        self.color_scale_choice.Select(0)
        self.x_scale_choice = ComboBox(self,
                                       -1,
                                       choices=[LINEAR_SCALE, LOG_SCALE],
                                       style=wx.CB_READONLY)
        self.x_scale_choice.Select(0)
        self.y_scale_choice = ComboBox(self,
                                       -1,
                                       choices=[LINEAR_SCALE, LOG_SCALE],
                                       style=wx.CB_READONLY)
        self.y_scale_choice.Select(0)
        self.filter_choice = ui.FilterComboBox(self, style=wx.CB_READONLY)
        self.gate_choice = ui.GateComboBox(self, style=wx.CB_READONLY)
        self.update_chart_btn = wx.Button(self, -1, "Update Chart")

        self.update_x_choices()
        self.update_y_choices()

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "x-axis:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.x_table_choice, 1, wx.EXPAND)
        sz.AddSpacer((3, -1))
        sz.Add(self.x_choice, 2, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "scale:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.x_scale_choice)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "y-axis:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.y_table_choice, 1, wx.EXPAND)
        sz.AddSpacer((3, -1))
        sz.Add(self.y_choice, 2, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "scale:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.y_scale_choice)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "grid size:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.gridsize_input, 1, wx.TOP, 3)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, label='color map:'), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.colormap_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, label='color scale:'), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.color_scale_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 5))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "filter:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.filter_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "gate:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.gate_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 5))

        sizer.Add(self.update_chart_btn)

        wx.EVT_COMBOBOX(self.x_table_choice, -1, self.on_x_table_selected)
        wx.EVT_COMBOBOX(self.y_table_choice, -1, self.on_y_table_selected)
        self.gate_choice.addobserver(self.on_gate_selected)
        wx.EVT_COMBOBOX(self.colormap_choice, -1, self.on_cmap_selected)
        wx.EVT_BUTTON(self.update_chart_btn, -1, self.update_figpanel)

        self.SetSizer(sizer)
        self.Show(1)
class DataSourcePanel(wx.Panel):
    '''
    A panel with controls for selecting the source data for a histogramplot 
    '''
    def __init__(self, parent, figpanel, **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)

        # the panel to draw charts on
        self.SetBackgroundColour('white')  # color for the background of panel
        self.figpanel = figpanel

        sizer = wx.BoxSizer(wx.VERTICAL)

        self.table_choice = ui.TableComboBox(self, -1, style=wx.CB_READONLY)
        self.x_choice = ComboBox(self,
                                 -1,
                                 size=(200, -1),
                                 choices=[''],
                                 style=wx.CB_READONLY)
        self.x_choice.Select(0)
        self.bins_input = wx.SpinCtrl(self, -1, '100')
        self.bins_input.SetRange(1, 400)
        self.x_scale_choice = ComboBox(
            self,
            -1,
            choices=[LINEAR_SCALE, LOG_SCALE, LOG2_SCALE],
            style=wx.CB_READONLY)
        self.x_scale_choice.Select(0)
        self.y_scale_choice = ComboBox(self,
                                       -1,
                                       choices=[LINEAR_SCALE, LOG_SCALE],
                                       style=wx.CB_READONLY)
        self.y_scale_choice.Select(0)
        self.filter_choice = ui.FilterComboBox(self, style=wx.CB_READONLY)
        self.filter_choice.Select(0)
        self.gate_choice = ui.GateComboBox(self, style=wx.CB_READONLY)
        self.gate_choice.set_gatable_columns([self.x_column])
        self.update_chart_btn = wx.Button(self, -1, "Update Chart")

        self.update_column_fields()

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "x-axis:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.table_choice, 1, wx.EXPAND)
        sz.AddSpacer((3, -1))
        sz.Add(self.x_choice, 2, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "x-scale:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.x_scale_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "y-scale:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.y_scale_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "bins:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.bins_input)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "filter:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.filter_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "gate:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.gate_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sizer.Add(self.update_chart_btn)

        wx.EVT_COMBOBOX(self.table_choice, -1, self.on_table_selected)
        wx.EVT_BUTTON(self.update_chart_btn, -1, self.update_figpanel)
        self.gate_choice.addobserver(self.on_gate_selected)

        self.SetSizer(sizer)
        self.Show(1)

    @property
    def x_column(self):
        return sql.Column(
            self.table_choice.GetString(self.table_choice.GetSelection()),
            self.x_choice.GetString(self.x_choice.GetSelection()))

    @property
    def filter(self):
        return self.filter_choice.get_filter_or_none()

    def on_table_selected(self, evt):
        table = self.table_choice.Value
        if table == ui.TableComboBox.OTHER_TABLE:
            t = ui.get_other_table_from_user(self)
            if t is not None:
                self.table_choice.Items = self.table_choice.Items[:-1] + [
                    t
                ] + self.table_choice.Items[-1:]
                self.table_choice.Select(self.table_choice.Items.index(t))
            else:
                self.table_choice.Select(0)
                return
        self.update_column_fields()

    def on_gate_selected(self, gate_name):
        self.update_gate_helper()

    def update_gate_helper(self):
        gate_name = self.gate_choice.get_gatename_or_none()
        if gate_name:
            self.figpanel.gate_helper.set_displayed_gate(
                p.gates[gate_name], self.x_column, None)
        else:
            self.figpanel.gate_helper.disable()

    def update_column_fields(self):
        tablename = self.table_choice.GetString(
            self.table_choice.GetSelection())
        fieldnames = self.get_numeric_columns_from_table(tablename)
        self.x_choice.Clear()
        self.x_choice.AppendItems(fieldnames)
        self.x_choice.SetSelection(0)

    def get_numeric_columns_from_table(self, table):
        ''' Fetches names of numeric columns for the given table. '''
        measurements = db.GetColumnNames(table)
        types = db.GetColumnTypes(table)
        return [
            m for m, t in zip(measurements, types) if t in [float, int, long]
        ]

    def _plotting_per_object_data(self):
        return (p.object_table and p.object_table
                in [self.x_column.table, self.x_column.table]
                or (self.x_column.table != p.image_table
                    and db.adjacent(p.object_table, self.x_column.table)))

    def update_figpanel(self, evt=None):
        self.gate_choice.set_gatable_columns([self.x_column])
        points = self._load_points()
        bins = int(self.bins_input.GetValue())
        self.figpanel.set_x_label(self.x_column.col)
        self.figpanel.set_x_scale(
            self.x_scale_choice.GetString(self.x_scale_choice.GetSelection()))
        self.figpanel.set_y_scale(
            self.y_scale_choice.GetString(self.y_scale_choice.GetSelection()))
        self.figpanel.setpoints(points, bins)
        self.update_gate_helper()
        self.figpanel.draw()

    def _load_points(self):
        q = sql.QueryBuilder()
        select = [self.x_column]
        q.set_select_clause(select)
        if self.filter is not None:
            q.add_filter(self.filter)

        return np.array(db.execute(str(q))).T[0]

    def save_settings(self):
        '''save_settings is called when saving a workspace to file.
        returns a dictionary mapping setting names to values encoded as strings
        '''
        d = {
            'table':
            self.table_choice.GetString(self.table_choice.GetSelection()),
            'x-axis':
            self.x_choice.GetString(self.x_choice.GetSelection()),
            'bins':
            self.bins_input.GetValue(),
            'x-scale':
            self.x_scale_choice.GetString(self.x_scale_choice.GetSelection()),
            'y-scale':
            self.y_scale_choice.GetString(self.y_scale_choice.GetSelection()),
            'filter':
            self.filter_choice.GetString(self.filter_choice.GetSelection()),
            'x-lim':
            self.figpanel.subplot.get_xlim(),
            'y-lim':
            self.figpanel.subplot.get_ylim(),
        }
        if self.gate_choice.get_gatename_or_none():
            d['gate'] = self.gate_choice.GetString(
                self.gate_choice.GetSelection())
        return d

    def load_settings(self, settings):
        '''load_settings is called when loading a workspace from file.
        settings - a dictionary mapping setting names to values encoded as
                   strings.
        '''
        if 'table' in settings:
            self.table_choice.SetStringSelection(settings['table'])
            self.update_column_fields()
        if 'x-axis' in settings:
            self.x_choice.SetStringSelection(settings['x-axis'])
        if 'bins' in settings:
            self.bins_input.SetValue(int(settings['bins']))
        if 'x-scale' in settings:
            self.x_scale_choice.SetStringSelection(settings['x-scale'])
        if 'y-scale' in settings:
            self.y_scale_choice.SetStringSelection(settings['y-scale'])
        if 'filter' in settings:
            self.filter_choice.SetStringSelection(settings['filter'])
        self.update_figpanel()
        if 'x-lim' in settings:
            self.figpanel.subplot.set_xlim(eval(settings['x-lim']))
        if 'y-lim' in settings:
            self.figpanel.subplot.set_ylim(eval(settings['y-lim']))
        if 'gate' in settings:
            self.gate_choice.SetStringSelection(settings['gate'])
            self.figpanel.gate_helper.set_displayed_gate(
                p.gates[settings['gate']], self.x_column, None)
        self.figpanel.draw()
Example #15
0
class DataSourcePanel(wx.Panel):
    '''
    A panel with controls for selecting the source data for a densityplot 
    '''
    def __init__(self, parent, figpanel, **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)
        # the panel to draw charts on
        self.figpanel = figpanel

        sizer = wx.BoxSizer(wx.VERTICAL)

        self.x_table_choice = ui.TableComboBox(self, -1, style=wx.CB_READONLY)
        self.y_table_choice = ui.TableComboBox(self, -1, style=wx.CB_READONLY)
        self.x_choice = ComboBox(self,
                                 -1,
                                 size=(200, -1),
                                 style=wx.CB_READONLY)
        self.y_choice = ComboBox(self,
                                 -1,
                                 size=(200, -1),
                                 style=wx.CB_READONLY)
        self.gridsize_input = wx.TextCtrl(self, -1, '50')
        maps = [m for m in matplotlib.cm.datad.keys() if not m.endswith("_r")]
        maps.sort()
        self.colormap_choice = ComboBox(self,
                                        -1,
                                        choices=maps,
                                        style=wx.CB_READONLY)
        self.colormap_choice.SetSelection(maps.index('jet'))
        self.color_scale_choice = ComboBox(self,
                                           -1,
                                           choices=[LINEAR_SCALE, LOG_SCALE],
                                           style=wx.CB_READONLY)
        self.color_scale_choice.Select(0)
        self.x_scale_choice = ComboBox(self,
                                       -1,
                                       choices=[LINEAR_SCALE, LOG_SCALE],
                                       style=wx.CB_READONLY)
        self.x_scale_choice.Select(0)
        self.y_scale_choice = ComboBox(self,
                                       -1,
                                       choices=[LINEAR_SCALE, LOG_SCALE],
                                       style=wx.CB_READONLY)
        self.y_scale_choice.Select(0)
        self.filter_choice = ui.FilterComboBox(self, style=wx.CB_READONLY)
        self.gate_choice = ui.GateComboBox(self, style=wx.CB_READONLY)
        self.update_chart_btn = wx.Button(self, -1, "Update Chart")

        self.update_x_choices()
        self.update_y_choices()

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "x-axis:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.x_table_choice, 1, wx.EXPAND)
        sz.AddSpacer((3, -1))
        sz.Add(self.x_choice, 2, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "scale:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.x_scale_choice)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "y-axis:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.y_table_choice, 1, wx.EXPAND)
        sz.AddSpacer((3, -1))
        sz.Add(self.y_choice, 2, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "scale:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.y_scale_choice)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "grid size:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.gridsize_input, 1, wx.TOP, 3)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, label='color map:'), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.colormap_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, label='color scale:'), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.color_scale_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 5))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "filter:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.filter_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "gate:"), 0, wx.TOP, 4)
        sz.AddSpacer((3, -1))
        sz.Add(self.gate_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 5))

        sizer.Add(self.update_chart_btn)

        wx.EVT_COMBOBOX(self.x_table_choice, -1, self.on_x_table_selected)
        wx.EVT_COMBOBOX(self.y_table_choice, -1, self.on_y_table_selected)
        self.gate_choice.addobserver(self.on_gate_selected)
        wx.EVT_COMBOBOX(self.colormap_choice, -1, self.on_cmap_selected)
        wx.EVT_BUTTON(self.update_chart_btn, -1, self.update_figpanel)

        self.SetSizer(sizer)
        self.Show(1)

    @property
    def x_column(self):
        return sql.Column(self.x_table_choice.GetStringSelection(),
                          self.x_choice.GetStringSelection())

    @property
    def y_column(self):
        return sql.Column(self.y_table_choice.GetStringSelection(),
                          self.y_choice.GetStringSelection())

    @property
    def filter(self):
        return self.filter_choice.get_filter_or_none()

    def on_x_table_selected(self, evt):
        table = self.x_table_choice.Value
        if table == ui.TableComboBox.OTHER_TABLE:
            t = ui.get_other_table_from_user(self)
            if t is not None:
                self.x_table_choice.Items = self.x_table_choice.Items[:-1] + [
                    t
                ] + self.x_table_choice.Items[-1:]
                self.x_table_choice.Select(self.x_table_choice.Items.index(t))
                sel = self.y_table_choice.GetSelection()
                self.y_table_choice.Items = self.y_table_choice.Items[:-1] + [
                    t
                ] + self.y_table_choice.Items[-1:]
                self.y_table_choice.SetSelection(sel)
            else:
                self.x_table_choice.Select(0)
                return
        self.update_x_choices()

    def on_y_table_selected(self, evt):
        table = self.y_table_choice.Value
        if table == ui.TableComboBox.OTHER_TABLE:
            t = ui.get_other_table_from_user(self)
            if t is not None:
                self.y_table_choice.Items = self.y_table_choice.Items[:-1] + [
                    t
                ] + self.y_table_choice.Items[-1:]
                self.y_table_choice.Select(self.y_table_choice.Items.index(t))
                sel = self.x_table_choice.GetSelection()
                self.x_table_choice.Items = self.x_table_choice.Items[:-1] + [
                    t
                ] + self.x_table_choice.Items[-1:]
                self.x_table_choice.SetSelection(sel)
            else:
                self.y_table_choice.Select(0)
                return
        self.update_y_choices()

    def on_gate_selected(self, gate_name):
        self.update_gate_helper()

    def update_gate_helper(self):
        gate_name = self.gate_choice.get_gatename_or_none()
        if gate_name:
            self.figpanel.gate_helper.set_displayed_gate(
                p.gates[gate_name], self.x_column, self.y_column)
        else:
            self.figpanel.gate_helper.disable()

    def on_cmap_selected(self, evt):
        self.figpanel.set_colormap(self.colormap_choice.GetStringSelection())

    def update_x_choices(self):
        tablename = self.x_table_choice.Value
        fieldnames = db.GetColumnNames(
            tablename)  #get_numeric_columns_from_table(tablename)
        self.x_choice.Clear()
        self.x_choice.AppendItems(fieldnames)
        self.x_choice.SetSelection(0)

    def update_y_choices(self):
        tablename = self.y_table_choice.Value
        fieldnames = db.GetColumnNames(
            tablename)  #get_numeric_columns_from_table(tablename)
        self.y_choice.Clear()
        self.y_choice.AppendItems(fieldnames)
        self.y_choice.SetSelection(0)

    def get_numeric_columns_from_table(self, table):
        ''' Fetches names of numeric columns for the given table. '''
        measurements = db.GetColumnNames(table)
        types = db.GetColumnTypes(table)
        return [
            m for m, t in zip(measurements, types) if t in [float, int, long]
        ]

    def _plotting_per_object_data(self):
        return (p.object_table and p.object_table
                in [self.x_column.table, self.x_column.table]
                or (self.x_column.table != p.image_table
                    and db.adjacent(p.object_table, self.x_column.table))
                or (self.y_column.table != p.image_table
                    and db.adjacent(p.object_table, self.y_column.table)))

    def update_figpanel(self, evt=None):
        self.gate_choice.set_gatable_columns([self.x_column, self.y_column])
        points = self._load_points()
        self.figpanel.setgridsize(int(self.gridsize_input.GetValue()))
        self.figpanel.set_x_scale(self.x_scale_choice.GetStringSelection())
        self.figpanel.set_y_scale(self.y_scale_choice.GetStringSelection())
        self.figpanel.set_color_scale(
            self.color_scale_choice.GetStringSelection())
        self.figpanel.set_x_label(self.x_column.col)
        self.figpanel.set_y_label(self.y_column.col)
        self.figpanel.set_colormap(self.colormap_choice.GetStringSelection())
        self.figpanel.setpointslists(points)
        self.figpanel.draw()
        self.update_gate_helper()

    def _load_points(self):
        q = sql.QueryBuilder()
        select = [self.x_column, self.y_column]
        q.set_select_clause(select)
        if self.filter != None:
            q.add_filter(self.filter)

        return db.execute(str(q))

    def save_settings(self):
        '''save_settings is called when saving a workspace to file.
        returns a dictionary mapping setting names to values encoded as strings
        '''
        d = {
            'x-table': self.x_table_choice.GetStringSelection(),
            'y-table': self.x_table_choice.GetStringSelection(),
            'x-axis': self.x_choice.GetStringSelection(),
            'y-axis': self.y_choice.GetStringSelection(),
            'x-scale': self.x_scale_choice.GetStringSelection(),
            'y-scale': self.y_scale_choice.GetStringSelection(),
            'grid size': self.gridsize_input.GetValue(),
            'colormap': self.colormap_choice.GetStringSelection(),
            'color scale': self.color_scale_choice.GetStringSelection(),
            'filter': self.filter_choice.GetStringSelection(),
            'x-lim': self.figpanel.subplot.get_xlim(),
            'y-lim': self.figpanel.subplot.get_ylim(),
            'version': '1',
        }
        if self.gate_choice.get_gatename_or_none():
            d['gate'] = self.gate_choice.GetStringSelection()
        return d

    def load_settings(self, settings):
        '''load_settings is called when loading a workspace from file.
        settings - a dictionary mapping setting names to values encoded as
                   strings.
        '''
        if 'version' not in settings:
            if 'table' in settings:
                settings['x-table'] = settings['table']
                settings['y-table'] = settings['table']
            settings['version'] = '1'
        if 'x-table' in settings:
            self.x_table_choice.SetStringSelection(settings['x-table'])
            self.update_x_choices()
        if 'y-table' in settings:
            self.y_table_choice.SetStringSelection(settings['y-table'])
            self.update_y_choices()
        if 'x-axis' in settings:
            self.x_choice.SetStringSelection(settings['x-axis'])
        if 'y-axis' in settings:
            self.y_choice.SetStringSelection(settings['y-axis'])
        if 'x-scale' in settings:
            self.x_scale_choice.SetStringSelection(settings['x-scale'])
        if 'y-scale' in settings:
            self.y_scale_choice.SetStringSelection(settings['y-scale'])
        if 'grid size' in settings:
            self.gridsize_input.SetValue(settings['grid size'])
        if 'colormap' in settings:
            self.colormap_choice.SetStringSelection(settings['colormap'])
        if 'color scale' in settings:
            self.color_scale_choice.SetStringSelection(settings['color scale'])
        if 'filter' in settings:
            self.filter_choice.SetStringSelection(settings['filter'])
        self.update_figpanel()
        if 'x-lim' in settings:
            self.figpanel.subplot.set_xlim(eval(settings['x-lim']))
        if 'y-lim' in settings:
            self.figpanel.subplot.set_ylim(eval(settings['y-lim']))
        if 'gate' in settings:
            self.gate_choice.SetStringSelection(settings['gate'])
            self.figpanel.gate_helper.set_displayed_gate(
                p.gates[settings['gate']], self.x_column, self.y_column)
        self.figpanel.draw()
Example #16
0
class DataSourcePanel(wx.Panel):
    '''
    A panel with controls for selecting the source data for a boxplot 
    '''
    def __init__(self, parent, figpanel, **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)
        
        # the panel to draw charts on
        self.figpanel = figpanel
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        
        self.x_columns = [] # column names to plot if selecting multiple columns

        self.table_choice = ui.TableComboBox(self, -1, style=wx.CB_READONLY)
        self.x_choice = ComboBox(self, -1, size=(200,-1), style=wx.CB_READONLY)
        self.x_multiple = wx.Button(self, -1, 'select multiple')
        self.group_choice = ComboBox(self, -1, choices=[NO_GROUP]+p._groups_ordered, style=wx.CB_READONLY)
        self.group_choice.Select(0)
        self.filter_choice = ui.FilterComboBox(self, style=wx.CB_READONLY)
        self.update_chart_btn = wx.Button(self, -1, "Update Chart")
        
        self.update_column_fields()
        
        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "table:"), 0, wx.TOP, 4)
        sz.AddSpacer((3,-1))
        sz.Add(self.table_choice, 1, wx.EXPAND)
        sz.AddSpacer((3,-1))
        sz.Add(wx.StaticText(self, -1, "measurement:"), 0, wx.TOP, 4)
        sz.AddSpacer((3,-1))
        sz.Add(self.x_choice, 2, wx.EXPAND)
        sz.AddSpacer((3,-1))
        sz.Add(self.x_multiple, 0, wx.EXPAND|wx.TOP, 2)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1,3))
        
        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "group x-axis by:"), 0, wx.TOP, 4)
        sz.AddSpacer((3,-1))
        sz.Add(self.group_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1,3))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "filter:"), 0, wx.TOP, 4)
        sz.AddSpacer((3,-1))
        sz.Add(self.filter_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1,3))
        
        sizer.Add(self.update_chart_btn)    
        
        wx.EVT_BUTTON(self.x_multiple, -1, self.on_select_multiple)
        wx.EVT_COMBOBOX(self.table_choice, -1, self.on_table_selected)
        wx.EVT_COMBOBOX(self.x_choice, -1, self.on_column_selected)
        wx.EVT_BUTTON(self.update_chart_btn, -1, self.update_figpanel)   
        
        self.SetSizer(sizer)
        self.Show(1)

    def on_select_multiple(self, evt):
        tablename = self.table_choice.GetStringSelection()
        column_names = self.get_numeric_columns_from_table(tablename)
        dlg = wx.MultiChoiceDialog(self, 
                                   'Select the columns you would like to plot',
                                   'Select Columns', column_names)
        dlg.SetSelections([column_names.index(v) for v in self.x_columns])
        if (dlg.ShowModal() == wx.ID_OK):
            self.x_choice.SetValue(SELECT_MULTIPLE)
            self.x_columns = [column_names[i] for i in dlg.GetSelections()]
            self.group_choice.Disable()
            self.group_choice.SetStringSelection(NO_GROUP)
        
    def on_table_selected(self, evt):
        table = self.table_choice.Value
        if table == ui.TableComboBox.OTHER_TABLE:
            t = ui.get_other_table_from_user(self)
            if t is not None:
                self.table_choice.Items = self.table_choice.Items[:-1] + [t] + self.table_choice.Items[-1:]
                self.table_choice.Select(self.table_choice.Items.index(t))
            else:
                self.table_choice.Select(0)
                return
        self.group_choice.Enable()
        self.x_columns = []
        self.update_column_fields()
        
    def on_column_selected(self, evt):
        self.group_choice.Enable()        
    
    def update_column_fields(self):
        tablename = self.table_choice.GetStringSelection()
        fieldnames = self.get_numeric_columns_from_table(tablename)
        self.x_choice.Clear()
        self.x_choice.AppendItems(fieldnames)
        self.x_choice.SetSelection(0)

    def get_numeric_columns_from_table(self, table):
        ''' Fetches names of numeric columns for the given table. '''
        measurements = db.GetColumnNames(table)
        types = db.GetColumnTypes(table)
        return [m for m,t in zip(measurements, types) if t in [float, int, long]]
        
    def update_figpanel(self, evt=None):
        table = self.table_choice.Value
        fltr = self.filter_choice.get_filter_or_none()
        grouping = self.group_choice.Value
        if self.x_choice.Value == SELECT_MULTIPLE:
            points_dict = {}
            for col in self.x_columns:
                pts = self.loadpoints(table, col, fltr, NO_GROUP)
                for k in pts.keys(): assert k not in points_dict.keys()
                points_dict.update(pts)
        else:
            col = self.x_choice.Value
            points_dict = self.loadpoints(table, col, fltr, grouping)
        
        # Check if the user is creating a plethora of plots by accident
        if 100 >= len(points_dict) > 25:
            res = wx.MessageDialog(self, 'Are you sure you want to show %s box '
                                   'plots on one axis?'%(len(points_dict)), 
                                   'Warning', style=wx.YES_NO|wx.NO_DEFAULT
                                   ).ShowModal()
            if res != wx.ID_YES:
                return
        elif len(points_dict) > 100:
            wx.MessageBox('Sorry, boxplot can not show more than 100 plots on\n'
                          'a single axis. Your current settings would plot %d.\n'
                          'Try using a filter to narrow your query.'
                          %(len(points_dict)), 'Too many groups to plot')
            return

        self.figpanel.setpoints(points_dict)
        if self.group_choice.Value != NO_GROUP:
            self.figpanel.set_x_axis_label(grouping)
            self.figpanel.set_y_axis_label(self.x_choice.Value)
        self.figpanel.draw()
        
    def loadpoints(self, tablename, col, fltr=None, grouping=NO_GROUP):
        '''
        Returns a dict mapping x label values to lists of values from col
        '''
        q = sql.QueryBuilder()
        select = [sql.Column(tablename, col)]
        if grouping != NO_GROUP:
            dm = datamodel.DataModel.getInstance()
            group_cols = dm.GetGroupColumnNames(grouping, include_table_name=True)
            select += [sql.Column(*col.split('.')) for col in group_cols]
        q.set_select_clause(select)
        if fltr is not None:
            q.add_filter(fltr)

        res = db.execute(str(q))
        res = np.array(res, dtype=object)
        # replaces Nones with NaNs
        for row in res:
            if row[0] is None:
                row[0] = np.nan
        
        points_dict = {}
        if self.group_choice.Value != NO_GROUP:
            for row in res:
                groupkey = tuple(row[1:])
                points_dict[groupkey] = points_dict.get(groupkey, []) + [row[0]]
        else:
            points_dict = {col : [r[0] for r in res]}
        return points_dict

    def save_settings(self):
        '''
        Called when saving a workspace to file.
        returns a dictionary mapping setting names to values encoded as strings
        '''
        if self.x_choice.Value == SELECT_MULTIPLE:
            cols = self.x_columns
        else:
            cols = [self.x_choice.GetStringSelection()]
        return {'table'  : self.table_choice.Value,
                'x-axis' : ','.join(cols),
                'filter' : self.filter_choice.Value,
                'x-lim'  : self.figpanel.subplot.get_xlim(),
                'y-lim'  : self.figpanel.subplot.get_ylim(),
##                'grouping': self.group_choice.Value,
##                'version': '1',
                }
    
    def load_settings(self, settings):
        '''load_settings is called when loading a workspace from file.
        
        settings - a dictionary mapping setting names to values encoded as
                   strings.
        '''
##        if 'version' not in settings:
##            settings['grouping'] = NO_GROUP
##            settings['version'] = '1'
        if 'table' in settings:
            self.table_choice.SetStringSelection(settings['table'])
            self.update_column_fields()
        if 'x-axis' in settings:
            cols = map(str.strip, settings['x-axis'].split(','))
            if len(cols) == 1:
                self.x_choice.SetStringSelection(cols[0])
            else:
                self.x_choice.SetValue(SELECT_MULTIPLE)
                self.x_columns = cols
        if 'filter' in settings:
            self.filter_choice.SetStringSelection(settings['filter'])
        self.update_figpanel()
        if 'x-lim' in settings:
            self.figpanel.subplot.set_xlim(eval(settings['x-lim']))
        if 'y-lim' in settings:
            self.figpanel.subplot.set_ylim(eval(settings['y-lim']))
        self.figpanel.draw()
Example #17
0
class ColumnFilterPanel(wx.Panel):
    '''
    Creates a UI that allows the user to create WHERE clauses by selecting 
    1) a DB column name, 2) a comparator, and 3) a value
    '''
    def __init__(self,
                 parent,
                 tables,
                 allow_delete=True,
                 expression=None,
                 **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)

        self.fieldSets = []
        self.tables = tables
        self.types = {}
        self.types[p.image_table] = db.GetColumnTypes(p.image_table)
        self.tableChoice = ComboBox(self,
                                    choices=self.tables,
                                    size=(150, -1),
                                    style=wx.CB_READONLY)
        self.tableChoice.Select(0)
        self.colChoice = ComboBox(self,
                                  choices=db.GetColumnNames(p.image_table),
                                  size=(150, -1),
                                  style=wx.CB_READONLY)
        self.colChoice.Select(0)
        self.comparatorChoice = ComboBox(self, size=(80, -1))
        self.update_comparator_choice()
        self.valueField = wx.ComboBox(self, -1, value='')
        if allow_delete:
            self.x_btn = wx.Button(self, -1, 'x', size=(30, -1))

##        if expression is not None:
##            self.set_expression(expression)

        colSizer = wx.BoxSizer(wx.HORIZONTAL)
        colSizer.Add(self.tableChoice, 1, wx.EXPAND)
        colSizer.AddSpacer((5, -1))
        colSizer.Add(self.colChoice, 1, wx.EXPAND)
        colSizer.AddSpacer((5, -1))
        colSizer.Add(self.comparatorChoice, 0.5, wx.EXPAND)
        colSizer.AddSpacer((5, -1))
        colSizer.Add(self.valueField, 1, wx.EXPAND)
        if allow_delete:
            colSizer.AddSpacer((5, -1))
            colSizer.Add(self.x_btn, 0, wx.EXPAND)

        self.SetSizer(colSizer)
        self.tableChoice.Bind(wx.EVT_COMBOBOX, self.on_select_table)
        self.colChoice.Bind(wx.EVT_COMBOBOX, self.on_select_col)
        if allow_delete:
            self.x_btn.Bind(wx.EVT_BUTTON, self.on_remove)
        self.Fit()

    def on_remove(self, evt):
        self.GrandParent.remove(self)

    def on_select_col(self, evt):
        self.update_comparator_choice()
        self.update_value_choice()

    def on_select_table(self, evt):
        self.update_col_choice()
        self.update_comparator_choice()
        self.update_value_choice()

    def update_col_choice(self):
        table = self.tableChoice.Value
        self.colChoice.SetItems(db.GetColumnNames(table))
        self.colChoice.Select(0)

    def _get_col_type(self):
        table = self.tableChoice.Value
        colidx = self.colChoice.GetSelection()
        return db.GetColumnTypes(table)[colidx]

    def update_comparator_choice(self):
        coltype = self._get_col_type()
        comparators = []
        if coltype in [str, unicode]:
            comparators = ['=', '!=', 'REGEXP', 'IS', 'IS NOT']
        if coltype in [int, float, long]:
            comparators = ['=', '!=', '<', '>', '<=', '>=', 'IS', 'IS NOT']
        self.comparatorChoice.SetItems(comparators)
        self.comparatorChoice.Select(0)

    def update_value_choice(self):
        table = self.tableChoice.Value
        column = self.colChoice.Value
        colidx = self.colChoice.GetSelection()
        coltype = db.GetColumnTypes(table)[colidx]
        vals = []
        # if coltype == str:# or coltype == int or coltype == long:
        #     res = db.execute('SELECT DISTINCT %s FROM %s ORDER BY %s'%(column, table, column))
        #     vals = [str(row[0]) for row in res]
        self.valueField.SetItems(vals)

    def get_filter(self):
        table = self.tableChoice.Value
        column = self.colChoice.Value
        comparator = self.comparatorChoice.GetValue()
        value = self.valueField.GetValue()
        if self._get_col_type() in [int, float, long]:
            # Don't quote numbers
            return sql.Filter(sql.Column(table, column), comparator,
                              '%s' % (value))
        if comparator.upper() in ['IS', 'IS NOT'] and value.upper() == 'NULL':
            # Don't quote comparisons to NULL
            return sql.Filter(sql.Column(table, column), comparator,
                              '%s' % (value))
        return sql.Filter(sql.Column(table, column), comparator,
                          '"%s"' % (value))
Example #18
0
class PlateViewer(wx.Frame, CPATool):
    def __init__(self, parent, size=(800,-1), **kwargs):
        wx.Frame.__init__(self, parent, -1, size=size, title='Plate Viewer', **kwargs)
        CPATool.__init__(self)
        self.SetName(self.tool_name)
        self.SetBackgroundColour("white") # Fixing the color

        # Check for required properties fields.
        fail = False
        for field in required_fields:
            if not p.field_defined(field):
                fail = True
                raise Exception('Properties field "%s" is required for PlateViewer.'%(field))
        if fail:    
            self.Destroy()
            return

        self.chMap = p.image_channel_colors[:]

        self.menuBar = wx.MenuBar()
        self.SetMenuBar(self.menuBar)
        self.fileMenu = wx.Menu()
        self.exitMenuItem = self.fileMenu.Append(id=wx.ID_EXIT, text='Exit\tCtrl+Q', help='Close Plate Viewer')
        self.GetMenuBar().Append(self.fileMenu, 'File')
        self.menuBar.Append(cpa.helpmenu.make_help_menu(self), 'Help')
        save_csv_menu_item = self.fileMenu.Append(-1, 'Save table to CSV\tCtrl+S')
        self.Bind(wx.EVT_MENU, self.on_save_csv, save_csv_menu_item)
        
        wx.EVT_MENU(self, wx.ID_EXIT, lambda _:self.Close())

        dataSourceSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='Source:'), wx.VERTICAL)
        dataSourceSizer.Add(wx.StaticText(self, label='Data source:'))
        self.sourceChoice = TableComboBox(self, -1, size=fixed_width)
        dataSourceSizer.Add(self.sourceChoice)
        dataSourceSizer.AddSpacer((-1,3))
        dataSourceSizer.Add(wx.StaticText(self, label='Measurement:'))
        measurements = get_non_blob_types_from_table(p.image_table)
        self.measurementsChoice = ComboBox(self, choices=measurements, size=fixed_width)
        self.measurementsChoice.Select(0)
        dataSourceSizer.Add(self.measurementsChoice)
        dataSourceSizer.Add(wx.StaticText(self, label='Filter:'))
        self.filterChoice = FilterComboBox(self, size=fixed_width)
        dataSourceSizer.Add(self.filterChoice)
        
        groupingSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='Data aggregation:'), wx.VERTICAL)
        groupingSizer.Add(wx.StaticText(self, label='Aggregation method:'))
        aggregation = ['mean', 'sum', 'median', 'stdev', 'cv%', 'min', 'max']
        self.aggregationMethodsChoice = ComboBox(self, choices=aggregation, size=fixed_width)
        self.aggregationMethodsChoice.Select(0)
        groupingSizer.Add(self.aggregationMethodsChoice)

        viewSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='View options:'), wx.VERTICAL)
        viewSizer.Add(wx.StaticText(self, label='Color map:'))
        maps = [m for m in matplotlib.cm.datad.keys() if not m.endswith("_r")]
        maps.sort()
        self.colorMapsChoice = ComboBox(self, choices=maps, size=fixed_width)
        self.colorMapsChoice.SetSelection(maps.index('jet'))
        viewSizer.Add(self.colorMapsChoice)

        viewSizer.AddSpacer((-1,3))
        viewSizer.Add(wx.StaticText(self, label='Well display:'))
        if p.image_thumbnail_cols:
            choices = pmp.all_well_shapes
        else:
            choices = list(pmp.all_well_shapes)
            choices.remove(pmp.THUMBNAIL)
        self.wellDisplayChoice = ComboBox(self, choices=choices, size=fixed_width)
        self.wellDisplayChoice.Select(0)
        viewSizer.Add(self.wellDisplayChoice)

        viewSizer.AddSpacer((-1,3))
        viewSizer.Add(wx.StaticText(self, label='Number of plates:'))
        self.numberOfPlatesTE = wx.TextCtrl(self, -1, '1', style=wx.TE_PROCESS_ENTER)
        viewSizer.Add(self.numberOfPlatesTE)
        if not p.plate_id:
            self.numberOfPlatesTE.Disable()

        annotationSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='Annotation:'), wx.VERTICAL)
        annotationSizer.Add(wx.StaticText(self, label='Annotation column:'))
        annotationColSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.annotation_cols = dict([(col, db.GetColumnType(p.image_table, col)) 
                                     for col in db.GetUserColumnNames(p.image_table)])
        self.annotationCol = ComboBox(self, choices=self.annotation_cols.keys(), size=(120,-1))
        if len(self.annotation_cols) > 0:
            self.annotationCol.SetSelection(0)
        annotationColSizer.Add(self.annotationCol, flag=wx.ALIGN_CENTER_VERTICAL)
        annotationColSizer.AddSpacer((3,-1))
        self.addAnnotationColBtn = wx.Button(self, -1, 'Add', size=(44,-1))
        annotationColSizer.Add(self.addAnnotationColBtn, flag=wx.ALIGN_CENTER_VERTICAL)
        annotationSizer.Add(annotationColSizer)
        annotationSizer.AddSpacer((-1,3))
        annotationSizer.Add(wx.StaticText(self, label='Label:'))
        self.annotationLabel = wx.TextCtrl(self, -1, 'Select wells')#, style=wx.TE_PROCESS_ENTER)
        self.annotationLabel.Disable()
        self.annotationLabel.SetForegroundColour(wx.Colour(80,80,80))
        self.annotationLabel.SetBackgroundColour(wx.LIGHT_GREY)
        annotationSizer.Add(self.annotationLabel)
        annotationSizer.AddSpacer((-1,3))
        self.outlineMarked = wx.CheckBox(self, -1, label='Outline annotated wells')
        annotationSizer.Add(self.outlineMarked)
        annotationSizer.AddSpacer((-1,3))
        self.annotationShowVals = wx.CheckBox(self, -1, label='Show values on plate')
        annotationSizer.Add(self.annotationShowVals)
        if len(db.GetUserColumnNames(p.image_table)) == 0:
            self.outlineMarked.Disable()
            self.annotationShowVals.Disable()
            
        controlSizer = wx.BoxSizer(wx.VERTICAL)
        controlSizer.Add(dataSourceSizer, 0, wx.EXPAND)
        controlSizer.AddSpacer((-1,3))
        controlSizer.Add(groupingSizer, 0, wx.EXPAND)
        controlSizer.AddSpacer((-1,3))
        controlSizer.Add(viewSizer, 0, wx.EXPAND)
        controlSizer.AddSpacer((-1,3))
        controlSizer.Add(annotationSizer, 0 , wx.EXPAND)

        self.plateMapSizer = wx.GridSizer(1,1,5,5)
        self.plateMaps = []
        self.plateMapChoices = []

        self.rightSizer = wx.BoxSizer(wx.VERTICAL)
        self.rightSizer.Add(self.plateMapSizer, 1, wx.EXPAND|wx.BOTTOM, 10)
        self.colorBar = ColorBarPanel(self, 'jet', size=(-1,25))
        self.rightSizer.Add(self.colorBar, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL)

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(controlSizer, 0, wx.LEFT|wx.TOP|wx.BOTTOM, 10)
        mainSizer.Add(self.rightSizer, 1, wx.EXPAND|wx.ALL, 10)

        self.SetSizer(mainSizer)
        self.SetClientSize((self.Size[0],self.Sizer.CalcMin()[1]))

        self.sourceChoice.Bind(wx.EVT_COMBOBOX, self.UpdateMeasurementChoice)
        self.measurementsChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectMeasurement)
        self.measurementsChoice.Select(0)
        self.aggregationMethodsChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectAggregationMethod)
        self.colorMapsChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectColorMap)
        self.numberOfPlatesTE.Bind(wx.EVT_TEXT_ENTER, self.OnEnterNumberOfPlates)
        self.wellDisplayChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectWellDisplay)
        self.annotationCol.Bind(wx.EVT_COMBOBOX, self.OnSelectAnnotationCol)
        self.addAnnotationColBtn.Bind(wx.EVT_BUTTON, self.OnAddAnnotationCol)
        self.annotationLabel.Bind(wx.EVT_KEY_UP, self.OnEnterAnnotation)
        self.outlineMarked.Bind(wx.EVT_CHECKBOX, self.OnOutlineMarked)
        self.annotationShowVals.Bind(wx.EVT_CHECKBOX, self.OnShowAnnotationValues)
        self.filterChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectFilter)

        self.AddPlateMap()
        self.OnSelectMeasurement()


    def AddPlateMap(self, plateIndex=0):
        '''
        Adds a new blank plateMap to the PlateMapSizer.
        '''
        data = np.ones(p.plate_shape)

        # Try to get explicit labels for all wells.
        res = db.execute('SELECT DISTINCT %s FROM %s WHERE %s != "" and %s IS NOT NULL'%
                         (dbconnect.UniqueWellClause(), p.image_table, p.well_id, p.well_id))

        if p.plate_id:
            self.plateMapChoices += [ComboBox(self, choices=db.GetPlateNames(), size=(400,-1))]
            self.plateMapChoices[-1].Select(plateIndex)
            self.plateMapChoices[-1].Bind(wx.EVT_COMBOBOX, self.OnSelectPlate)
    
            #plate_col_type = db.GetColumnType(p.image_table, p.plate_id)
            #plate_id = plate_col_type(self.plateMapChoices[-1].GetString(plateIndex))
            
            plateMapChoiceSizer = wx.BoxSizer(wx.HORIZONTAL)
            plateMapChoiceSizer.Add(wx.StaticText(self, label='Plate:'), flag=wx.ALIGN_CENTER_VERTICAL)
            plateMapChoiceSizer.Add(self.plateMapChoices[-1], flag=wx.ALIGN_CENTER_VERTICAL)
        well_keys = res

        platemap = pmp.PlateMapPanel(self, data, well_keys, p.plate_shape,
                                     colormap = self.colorMapsChoice.Value,
                                     well_disp = self.wellDisplayChoice.Value)
        platemap.add_well_selection_handler(self.OnSelectWell)
        self.plateMaps += [platemap]

        singlePlateMapSizer = wx.BoxSizer(wx.VERTICAL)
        if p.plate_id:
            singlePlateMapSizer.Add(plateMapChoiceSizer, 0, wx.ALIGN_CENTER)
        singlePlateMapSizer.Add(platemap, 1, wx.EXPAND|wx.ALIGN_CENTER)

        self.plateMapSizer.Add(singlePlateMapSizer, 1, wx.EXPAND|wx.ALIGN_CENTER)

    def UpdatePlateMaps(self):
        self.measurement = self.measurementsChoice.Value
        measurement = self.measurement
        table       = self.sourceChoice.Value
        self.aggMethod   = self.aggregationMethodsChoice.Value
        categorical = measurement not in get_numeric_columns_from_table(table)
        fltr        = self.filterChoice.Value
        self.colorBar.ClearNotifyWindows()

        q = sql.QueryBuilder()
        well_key_cols = [sql.Column(p.image_table, col) for col in well_key_columns()]
        select = list(well_key_cols)
        if not categorical:
            if self.aggMethod=='mean':
                select += [sql.Column(table, measurement, 'AVG')]
            elif self.aggMethod=='stdev':
                select += [sql.Column(table, measurement, 'STDDEV')]
            elif self.aggMethod=='cv%':
                # stddev(col) / avg(col) * 100
                select += [sql.Expression(
                              sql.Column(table, measurement, 'STDDEV'), ' / ',
                              sql.Column(table, measurement, 'AVG'), ' * 100')]
            elif self.aggMethod=='sum':
                select += [sql.Column(table, measurement, 'SUM')]
            elif self.aggMethod=='min':
                select += [sql.Column(table, measurement, 'MIN')]
            elif self.aggMethod=='max':
                select += [sql.Column(table, measurement, 'MAX')]
            elif self.aggMethod=='median':
                select += [sql.Column(table, measurement, 'MEDIAN')]
            elif self.aggMethod=='none':
                select += [sql.Column(table, measurement)]
        else:
            select += [sql.Column(table, measurement)]
        
        q.set_select_clause(select)
        q.set_group_columns(well_key_cols)
        if fltr not in (FilterComboBox.NO_FILTER, FilterComboBox.NEW_FILTER, ''):
            if fltr in p._filters:
                q.add_filter(p._filters[fltr])
            elif fltr in p.gates:
                q.add_filter(p.gates[fltr].as_filter())
            else:
                raise Exception('Could not find filter "%s" in gates or filters'%(fltr))
        wellkeys_and_values = db.execute(str(q))
        wellkeys_and_values = np.array(wellkeys_and_values, dtype=object)

        # Replace measurement None's with nan
        for row in wellkeys_and_values:
            if row[-1] is None:
                row[-1] = np.nan

        data = []
        key_lists = []
        dmax = -np.inf
        dmin = np.inf
        if p.plate_id:
            for plateChoice, plateMap in zip(self.plateMapChoices, self.plateMaps):
                plate = plateChoice.Value
                plateMap.SetPlate(plate)
                self.colorBar.AddNotifyWindow(plateMap)
                self.keys_and_vals = [v for v in wellkeys_and_values if str(v[0])==plate]
                platedata, wellkeys, ignore = FormatPlateMapData(self.keys_and_vals, categorical)
                data += [platedata]
                key_lists += [wellkeys]
                if not categorical:
                    dmin = np.nanmin([float(kv[-1]) for kv in self.keys_and_vals]+[dmin])
                    dmax = np.nanmax([float(kv[-1]) for kv in self.keys_and_vals]+[dmax])
        else:
            self.colorBar.AddNotifyWindow(self.plateMaps[0])
            platedata, wellkeys, ignore = FormatPlateMapData(wellkeys_and_values, categorical)
            data += [platedata]
            key_lists += [wellkeys]
            if not categorical:
                dmin = np.nanmin([float(kv[-1]) for kv in wellkeys_and_values])
                dmax = np.nanmax([float(kv[-1]) for kv in wellkeys_and_values])
            
        if not categorical:
            if len(wellkeys_and_values) > 0:
                # Compute the global extents if there is any data whatsoever
                gmin = np.nanmin([float(vals[-1]) for vals in wellkeys_and_values])
                gmax = np.nanmax([float(vals[-1]) for vals in wellkeys_and_values])
                if np.isinf(dmin) or np.isinf(dmax):
                    gmin = gmax = dmin = dmax = 1.
                    # Warn if there was no data for this plate (and no filter was used)
                    if fltr == FilterComboBox.NO_FILTER:
                        wx.MessageBox('No numeric data was found in "%s.%s" for plate "%s"'
                                      %(table, measurement, plate), 'Warning')
            else:
                gmin = gmax = 1.
                if fltr == FilterComboBox.NO_FILTER:
                    wx.MessageBox('No numeric data was found in %s.%s'
                                  %(table, measurement), 'Warning')

        if categorical:
            self.colorBar.Hide()
        else:
            self.colorBar.Show()
            self.colorBar.SetLocalExtents([dmin,dmax])
            self.colorBar.SetGlobalExtents([gmin,gmax])
        self.rightSizer.Layout()

        for keys, d, plateMap in zip(key_lists, data, self.plateMaps):
            plateMap.SetWellKeys(keys)
            if categorical:
                plateMap.SetData(np.ones(d.shape) * np.nan)
                plateMap.SetTextData(d)
            else:
                plateMap.SetData(d, data_range=self.colorBar.GetLocalExtents(), 
                                 clip_interval=self.colorBar.GetLocalInterval(), 
                                 clip_mode=self.colorBar.GetClipMode())

        for keys, d, plateMap in zip(key_lists, data, self.plateMaps):
            plateMap.SetWellKeys(keys)
            if categorical:
                plateMap.SetData(np.ones(d.shape) * np.nan)
                plateMap.SetTextData(d)
            else:
                plateMap.SetData(d, data_range=self.colorBar.GetLocalExtents(), 
                                 clip_interval=self.colorBar.GetLocalInterval(), 
                                 clip_mode=self.colorBar.GetClipMode())

    def UpdateMeasurementChoice(self, evt=None):
        '''
        Handles the selection of a source table (per-image or per-object) from
        a choice box.  The measurement choice box is populated with the names
        of numeric columns from the selected table.
        '''
        table = self.sourceChoice.Value
        if table == TableComboBox.OTHER_TABLE:
            t = get_other_table_from_user(self)
            if t is not None:
                self.sourceChoice.Items = self.sourceChoice.Items[:-1] + [t] + self.sourceChoice.Items[-1:]
                self.sourceChoice.Select(self.sourceChoice.Items.index(t))
                table = t
            else:
                self.sourceChoice.Select(0)
                return
        self.measurementsChoice.SetItems(get_non_blob_types_from_table(table))
        self.measurementsChoice.Select(0)
        self.colorBar.ResetInterval()
        self.UpdatePlateMaps()

    def on_save_csv(self, evt):
        defaultFileName = 'my_plate_table.csv'
        saveDialog = wx.FileDialog(self, message="Save as:",
                                   defaultDir=os.getcwd(),
                                   defaultFile=defaultFileName,
                                   wildcard='csv|*',
                                   style=(wx.SAVE | wx.FD_OVERWRITE_PROMPT |
                                          wx.FD_CHANGE_DIR))
        if saveDialog.ShowModal() == wx.ID_OK:
            filename = saveDialog.GetPath()
            self.save_to_csv(filename)
            self.Title = filename
        saveDialog.Destroy()

    def save_to_csv(self, filename):
        with open(filename, 'wb') as f:
            w = csv.writer(f)
            w.writerow(['Plate', 'Well', self.measurement + ' ' + self.aggMethod])
            w.writerows(self.keys_and_vals)

        logging.info('Table saved to %s'%filename)

    def OnSelectPlate(self, evt):
        ''' Handles the selection of a plate from the plate choice box. '''
        self.UpdatePlateMaps()

    def OnSelectMeasurement(self, evt=None):
        ''' Handles the selection of a measurement to plot from a choice box. '''
        selected_measurement = self.measurementsChoice.Value 
        table = self.sourceChoice.Value
        numeric_measurements = get_numeric_columns_from_table(table)
        if (selected_measurement in numeric_measurements):
            self.aggregationMethodsChoice.Enable()
            self.colorMapsChoice.Enable()
        else:
            self.aggregationMethodsChoice.Disable()
            self.colorMapsChoice.Disable()
        self.colorBar.ResetInterval()
        self.UpdatePlateMaps()

    def OnSelectAggregationMethod(self, evt=None):
        ''' Handles the selection of an aggregation method from the choice box. '''
        self.colorBar.ResetInterval()
        self.UpdatePlateMaps()

    def OnSelectColorMap(self, evt=None):
        ''' Handles the selection of a color map from a choice box. '''
        map = self.colorMapsChoice.Value
        cm = matplotlib.cm.get_cmap(map)
        self.colorBar.SetMap(map)
        for plateMap in self.plateMaps:
            plateMap.SetColorMap(map)

    def OnSelectWellDisplay(self, evt=None):
        ''' Handles the selection of a well display choice from a choice box. '''
        sel = self.wellDisplayChoice.Value
        if sel.lower() == 'image':
            dlg = wx.MessageDialog(self, 
                'This mode will render each well as a shrunken image loaded '
                'from that well. This feature is currently VERY SLOW since it '
                'requires loading hundreds of full sized images. Are you sure '
                'you want to continue?',
                'Load all images?', wx.OK|wx.CANCEL|wx.ICON_QUESTION)
            if dlg.ShowModal() != wx.ID_OK:
                self.wellDisplayChoice.SetSelection(0)
                return
        if sel.lower() in ['image', 'thumbnail']:
            self.colorBar.Hide()
        else:
            self.colorBar.Show()
        for platemap in self.plateMaps:
            platemap.SetWellDisplay(sel)

    def OnEnterNumberOfPlates(self, evt=None):
        ''' Handles the entry of a plates to view from a choice box. '''
        try:
            nPlates = int(self.numberOfPlatesTE.GetValue())
        except:
            logging.warn('Invalid # of plates! Please enter a number between 1 and 100')
            return
        if nPlates>100:
            logging.warn('Too many plates! Please enter a number between 1 and 100')
            return
        if nPlates<1:
            logging.warn('You must display at least 1 plate.')
            self.numberOfPlatesTE.SetValue('1')
            nPlates = 1
        # Record the indices of the plates currently selected.
        # Pad the list with sequential plate indices then crop to the new number of plates.
        currentPlates = [plateChoice.GetSelection() for plateChoice in self.plateMapChoices]
        currentPlates = (currentPlates+[(currentPlates[-1]+1+p) % len(db.GetPlateNames()) for p in range(nPlates)])[:nPlates]
        # Remove all plateMaps
        self.plateMapSizer.Clear(deleteWindows=True)
        self.plateMaps = []
        self.plateMapChoices = []
        # Restructure the plateMapSizer appropriately
        rows = cols = np.ceil(np.sqrt(nPlates))
        self.plateMapSizer.SetRows(rows)
        self.plateMapSizer.SetCols(cols)
        # Add the plate maps
        for plateIndex in currentPlates:
            self.AddPlateMap(plateIndex)
        self.UpdatePlateMaps()
        self.plateMapSizer.Layout()
        # Update outlines
        self.OnOutlineMarked()
        
    def OnSelectWell(self):
        '''When wells are selected: display their annotation in the annotation
        label control. If multiple annotations are found then make sure the
        user knows.
        '''
        wellkeys = []
        for pm in self.plateMaps:
            wellkeys += pm.get_selected_well_keys()
        if len(wellkeys) > 0 and self.annotationCol.Value != '':
            self.annotationLabel.Enable()
            self.annotationLabel.SetForegroundColour(wx.BLACK)
            self.annotationLabel.SetBackgroundColour(wx.WHITE)
            annotations = db.execute('SELECT %s FROM %s WHERE %s'%(
                                self.annotationCol.Value, 
                                p.image_table, 
                                GetWhereClauseForWells(wellkeys)))
            annotations = list(set([a[0] for a in annotations]))
            if len(annotations) == 1:
                if annotations[0] == None:
                    self.annotationLabel.SetValue('')
                else:
                    self.annotationLabel.SetValue(str(annotations[0]))
            else:
                self.annotationLabel.SetValue(','.join([str(a) for a in annotations if a is not None]))
        else:
            self.annotationLabel.Disable()
            self.annotationLabel.SetForegroundColour(wx.Colour(80,80,80))
            self.annotationLabel.SetBackgroundColour(wx.LIGHT_GREY)
            self.annotationLabel.SetValue('Select wells')
                
    def OnAddAnnotationCol(self, evt):
        '''Add a new user annotation column to the database.
        '''
        dlg = wx.TextEntryDialog(self, 'New annotation column name: User_','Add Annotation Column')
        if dlg.ShowModal() != wx.ID_OK:
            return
        new_column = 'User_'+dlg.GetValue()
        # user-type ==> (sql-type, python-type)
        coltypes = {'Text'   : ('VARCHAR(255)', str), 
                    'Number' : ('FLOAT', float)}
        dlg = wx.SingleChoiceDialog(self, 
                'What type of annotation column would you like to add?\nThis can not be changed.',
                'Add Annotation Column', coltypes.keys(), wx.CHOICEDLG_STYLE)
        if dlg.ShowModal() != wx.ID_OK:
            return
        usertype = dlg.GetStringSelection()
        db.AppendColumn(p.image_table, new_column, coltypes[usertype][0])
        self.annotation_cols[new_column] = coltypes[usertype][1]
        self.annotationCol.Items += [new_column]
        self.annotationCol.SetSelection(len(self.annotation_cols) - 1)
        current_selection = self.measurementsChoice.Selection
        self.measurementsChoice.SetItems(self.measurementsChoice.Strings + [new_column])
        if self.annotationShowVals.IsChecked():
            column = self.annotationCol.Value
            self.sourceChoice.SetStringSelection(p.image_table)
            self.measurementsChoice.SetStringSelection(column)
            self.UpdatePlateMaps()
        else:
            self.measurementsChoice.SetSelection(current_selection[0])
        self.annotationShowVals.Enable()
        self.outlineMarked.Enable()
        self.OnSelectWell()
        
    def OnSelectAnnotationCol(self, evt=None):
        '''Handles selection of an annotation column.
        '''
        col = self.annotationCol.Value
        if col == '':
            return
        coltype = self.annotation_cols[col]
        self.OnSelectWell()
        self.OnOutlineMarked()
        if self.annotationShowVals.IsChecked():
            if coltype != str:
                self.colorMapsChoice.Enable()
            else:
                self.colorMapsChoice.Disable()
            self.measurementsChoice.SetStringSelection(col)
            self.UpdatePlateMaps()
        
    def OnEnterAnnotation(self, evt=None):
        '''Store the annotation value in the annotation column of the db.
        '''
        if evt.KeyCode < 32 or evt.KeyCode > 127:
            return
        column = self.annotationCol.Value
        value = self.annotationLabel.Value
        wellkeys = []
        for pm in self.plateMaps:
            wellkeys += pm.get_selected_well_keys()
        if value == '':
            value = None
        elif self.annotation_cols[column] == float:
            try:
                value = float(value)
                self.annotationLabel.SetForegroundColour(wx.BLACK)
            except:
                self.annotationLabel.SetForegroundColour(wx.Color(255,0,0))
                return
        db.UpdateWells(p.image_table, column, value, wellkeys)
        if self.outlineMarked.IsChecked():
            for pm in self.plateMaps:
                if value is None:
                    pm.UnOutlineWells(wellkeys)
                else:
                    pm.OutlineWells(wellkeys)
        if (self.sourceChoice.Value == p.image_table and 
            self.measurementsChoice.Value == column):
            self.UpdatePlateMaps()

    def OnOutlineMarked(self, evt=None):
        '''Outlines all non-NULL values of the current annotation
        '''
        # Disable filters when outlining marked wells
        #if self.outlineMarked.IsChecked():
            #self.filterChoice.SetStringSelection(FilterComboBox.NO_FILTER)
            #self.filterChoice.Disable()
        #else:
            #if not self.annotationShowVals.IsChecked():
                #self.filterChoice.Enable()
        # Update outlined wells in PlateMapPanels
        for pm in self.plateMaps:
            if self.outlineMarked.IsChecked():
                column = self.annotationCol.Value
                if p.plate_id:
                    res = db.execute('SELECT %s, %s FROM %s WHERE %s="%s"'%(
                        dbconnect.UniqueWellClause(), column, p.image_table, 
                        p.plate_id, pm.plate))
                else:
                    # if there's no plate_id, we assume there is only 1 plate
                    # and fetch all the data
                    res = db.execute('SELECT %s, %s FROM %s'%(
                        dbconnect.UniqueWellClause(), column, p.image_table))
                keys = [tuple(r[:-1]) for r in res if r[-1] is not None]
                pm.SetOutlinedWells(keys)
            else:
                pm.SetOutlinedWells([])
        self.UpdatePlateMaps()
                
    def OnShowAnnotationValues(self, evt=None):
        '''Handler for the show values checkbox.
        '''
        if self.annotationShowVals.IsChecked():
            column = self.annotationCol.Value
            self.sourceChoice.SetStringSelection(p.image_table)
            self.measurementsChoice.SetItems(get_non_blob_types_from_table(p.image_table))            
            self.measurementsChoice.SetStringSelection(column)
            self.filterChoice.SetStringSelection(FilterComboBox.NO_FILTER)
            self.sourceChoice.Disable()
            self.measurementsChoice.Disable()
            self.filterChoice.Disable()
            self.aggregationMethodsChoice.Disable()
            self.aggregationMethodsChoice.SetValue('none')
        else:
            self.sourceChoice.Enable()
            self.measurementsChoice.Enable()
            if not self.outlineMarked.IsChecked():
                self.filterChoice.Enable()
            if db.GetColumnType(self.sourceChoice.Value, self.measurementsChoice.Value) != str:
                self.aggregationMethodsChoice.Enable()
                self.aggregationMethodsChoice.SetSelection(0)
        self.UpdatePlateMaps() 
        
    def OnSelectFilter(self, evt):
        self.filterChoice.on_select(evt)
        self.UpdatePlateMaps()
        self.colorBar.ResetInterval()
        
    def save_settings(self):
        '''save_settings is called when saving a workspace to file.
        
        returns a dictionary mapping setting names to values encoded as strings
        '''
        settings = {'table' : self.sourceChoice.Value,
                    'measurement' : self.measurementsChoice.Value,
                    'aggregation' : self.aggregationMethodsChoice.Value,
                    'colormap' : self.colorMapsChoice.Value,
                    'well display' : self.wellDisplayChoice.Value,
                    'number of plates' : self.numberOfPlatesTE.GetValue(),
                    }
        for i, choice in enumerate(self.plateMapChoices):
            settings['plate %d'%(i+1)] = choice.Value
        return settings
    
    def load_settings(self, settings):
        '''load_settings is called when loading a workspace from file.
        
        settings - a dictionary mapping setting names to values encoded as
                   strings.
        '''
        if 'table' in settings:
            self.sourceChoice.SetStringSelection(settings['table'])
            self.UpdateMeasurementChoice()
        if 'measurement' in settings:
            self.measurementsChoice.SetStringSelection(settings['measurement'])
            self.OnSelectMeasurement()
        if 'aggregation' in settings:
            self.aggregationMethodsChoice.SetStringSelection(settings['aggregation'])
            self.OnSelectAggregationMethod()
        if 'colormap' in settings:
            self.colorMapsChoice.SetStringSelection(settings['colormap'])
            self.OnSelectColorMap()
        if 'number of plates' in settings:
            self.numberOfPlatesTE.SetValue(settings['number of plates'])
            self.OnEnterNumberOfPlates()
        for s, v in settings.items():
            if s.startswith('plate '):
                self.plateMapChoices[int(s.strip('plate ')) - 1].SetValue(v)
        # set well display last since each step currently causes a redraw and
        # this could take a long time if they are displaying images
        if 'well display' in settings:
            self.wellDisplayChoice.SetStringSelection(settings['well display'])
            self.OnSelectWellDisplay()
    def __init__(self, parent, figpanel, **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)

        # the panel to draw charts on
        self.SetBackgroundColour('white')  # color for the background of panel
        self.figpanel = figpanel

        sizer = wx.BoxSizer(wx.VERTICAL)

        self.table_choice = ui.TableComboBox(self, -1, style=wx.CB_READONLY)
        self.x_choice = ComboBox(self,
                                 -1,
                                 size=(200, -1),
                                 choices=[''],
                                 style=wx.CB_READONLY)
        self.x_choice.Select(0)
        self.bins_input = wx.SpinCtrl(self, -1, '100')
        self.bins_input.SetRange(1, 400)
        self.x_scale_choice = ComboBox(
            self,
            -1,
            choices=[LINEAR_SCALE, LOG_SCALE, LOG2_SCALE],
            style=wx.CB_READONLY)
        self.x_scale_choice.Select(0)
        self.y_scale_choice = ComboBox(self,
                                       -1,
                                       choices=[LINEAR_SCALE, LOG_SCALE],
                                       style=wx.CB_READONLY)
        self.y_scale_choice.Select(0)
        self.filter_choice = ui.FilterComboBox(self, style=wx.CB_READONLY)
        self.filter_choice.Select(0)
        self.gate_choice = ui.GateComboBox(self, style=wx.CB_READONLY)
        self.gate_choice.set_gatable_columns([self.x_column])
        self.update_chart_btn = wx.Button(self, -1, "Update Chart")

        self.update_column_fields()

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "x-axis:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.table_choice, 1, wx.EXPAND)
        sz.AddSpacer((3, -1))
        sz.Add(self.x_choice, 2, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "x-scale:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.x_scale_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "y-scale:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.y_scale_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "bins:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.bins_input)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "filter:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.filter_choice, 1, wx.EXPAND)
        sz.AddSpacer((5, -1))
        sz.Add(wx.StaticText(self, -1, "gate:"), 0, wx.TOP, 4)
        sz.AddSpacer((2, -1))
        sz.Add(self.gate_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 2))

        sizer.Add(self.update_chart_btn)

        wx.EVT_COMBOBOX(self.table_choice, -1, self.on_table_selected)
        wx.EVT_BUTTON(self.update_chart_btn, -1, self.update_figpanel)
        self.gate_choice.addobserver(self.on_gate_selected)

        self.SetSizer(sizer)
        self.Show(1)
Example #20
0
    def __init__(self, parent, size=(800,-1), **kwargs):
        wx.Frame.__init__(self, parent, -1, size=size, title='Plate Viewer', **kwargs)
        CPATool.__init__(self)
        self.SetName(self.tool_name)
        self.SetBackgroundColour("white") # Fixing the color

        # Check for required properties fields.
        fail = False
        for field in required_fields:
            if not p.field_defined(field):
                fail = True
                raise Exception('Properties field "%s" is required for PlateViewer.'%(field))
        if fail:    
            self.Destroy()
            return

        self.chMap = p.image_channel_colors[:]

        self.menuBar = wx.MenuBar()
        self.SetMenuBar(self.menuBar)
        self.fileMenu = wx.Menu()
        self.exitMenuItem = self.fileMenu.Append(id=wx.ID_EXIT, text='Exit\tCtrl+Q', help='Close Plate Viewer')
        self.GetMenuBar().Append(self.fileMenu, 'File')
        self.menuBar.Append(cpa.helpmenu.make_help_menu(self), 'Help')
        save_csv_menu_item = self.fileMenu.Append(-1, 'Save table to CSV\tCtrl+S')
        self.Bind(wx.EVT_MENU, self.on_save_csv, save_csv_menu_item)
        
        wx.EVT_MENU(self, wx.ID_EXIT, lambda _:self.Close())

        dataSourceSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='Source:'), wx.VERTICAL)
        dataSourceSizer.Add(wx.StaticText(self, label='Data source:'))
        self.sourceChoice = TableComboBox(self, -1, size=fixed_width)
        dataSourceSizer.Add(self.sourceChoice)
        dataSourceSizer.AddSpacer((-1,3))
        dataSourceSizer.Add(wx.StaticText(self, label='Measurement:'))
        measurements = get_non_blob_types_from_table(p.image_table)
        self.measurementsChoice = ComboBox(self, choices=measurements, size=fixed_width)
        self.measurementsChoice.Select(0)
        dataSourceSizer.Add(self.measurementsChoice)
        dataSourceSizer.Add(wx.StaticText(self, label='Filter:'))
        self.filterChoice = FilterComboBox(self, size=fixed_width)
        dataSourceSizer.Add(self.filterChoice)
        
        groupingSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='Data aggregation:'), wx.VERTICAL)
        groupingSizer.Add(wx.StaticText(self, label='Aggregation method:'))
        aggregation = ['mean', 'sum', 'median', 'stdev', 'cv%', 'min', 'max']
        self.aggregationMethodsChoice = ComboBox(self, choices=aggregation, size=fixed_width)
        self.aggregationMethodsChoice.Select(0)
        groupingSizer.Add(self.aggregationMethodsChoice)

        viewSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='View options:'), wx.VERTICAL)
        viewSizer.Add(wx.StaticText(self, label='Color map:'))
        maps = [m for m in matplotlib.cm.datad.keys() if not m.endswith("_r")]
        maps.sort()
        self.colorMapsChoice = ComboBox(self, choices=maps, size=fixed_width)
        self.colorMapsChoice.SetSelection(maps.index('jet'))
        viewSizer.Add(self.colorMapsChoice)

        viewSizer.AddSpacer((-1,3))
        viewSizer.Add(wx.StaticText(self, label='Well display:'))
        if p.image_thumbnail_cols:
            choices = pmp.all_well_shapes
        else:
            choices = list(pmp.all_well_shapes)
            choices.remove(pmp.THUMBNAIL)
        self.wellDisplayChoice = ComboBox(self, choices=choices, size=fixed_width)
        self.wellDisplayChoice.Select(0)
        viewSizer.Add(self.wellDisplayChoice)

        viewSizer.AddSpacer((-1,3))
        viewSizer.Add(wx.StaticText(self, label='Number of plates:'))
        self.numberOfPlatesTE = wx.TextCtrl(self, -1, '1', style=wx.TE_PROCESS_ENTER)
        viewSizer.Add(self.numberOfPlatesTE)
        if not p.plate_id:
            self.numberOfPlatesTE.Disable()

        annotationSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='Annotation:'), wx.VERTICAL)
        annotationSizer.Add(wx.StaticText(self, label='Annotation column:'))
        annotationColSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.annotation_cols = dict([(col, db.GetColumnType(p.image_table, col)) 
                                     for col in db.GetUserColumnNames(p.image_table)])
        self.annotationCol = ComboBox(self, choices=self.annotation_cols.keys(), size=(120,-1))
        if len(self.annotation_cols) > 0:
            self.annotationCol.SetSelection(0)
        annotationColSizer.Add(self.annotationCol, flag=wx.ALIGN_CENTER_VERTICAL)
        annotationColSizer.AddSpacer((3,-1))
        self.addAnnotationColBtn = wx.Button(self, -1, 'Add', size=(44,-1))
        annotationColSizer.Add(self.addAnnotationColBtn, flag=wx.ALIGN_CENTER_VERTICAL)
        annotationSizer.Add(annotationColSizer)
        annotationSizer.AddSpacer((-1,3))
        annotationSizer.Add(wx.StaticText(self, label='Label:'))
        self.annotationLabel = wx.TextCtrl(self, -1, 'Select wells')#, style=wx.TE_PROCESS_ENTER)
        self.annotationLabel.Disable()
        self.annotationLabel.SetForegroundColour(wx.Colour(80,80,80))
        self.annotationLabel.SetBackgroundColour(wx.LIGHT_GREY)
        annotationSizer.Add(self.annotationLabel)
        annotationSizer.AddSpacer((-1,3))
        self.outlineMarked = wx.CheckBox(self, -1, label='Outline annotated wells')
        annotationSizer.Add(self.outlineMarked)
        annotationSizer.AddSpacer((-1,3))
        self.annotationShowVals = wx.CheckBox(self, -1, label='Show values on plate')
        annotationSizer.Add(self.annotationShowVals)
        if len(db.GetUserColumnNames(p.image_table)) == 0:
            self.outlineMarked.Disable()
            self.annotationShowVals.Disable()
            
        controlSizer = wx.BoxSizer(wx.VERTICAL)
        controlSizer.Add(dataSourceSizer, 0, wx.EXPAND)
        controlSizer.AddSpacer((-1,3))
        controlSizer.Add(groupingSizer, 0, wx.EXPAND)
        controlSizer.AddSpacer((-1,3))
        controlSizer.Add(viewSizer, 0, wx.EXPAND)
        controlSizer.AddSpacer((-1,3))
        controlSizer.Add(annotationSizer, 0 , wx.EXPAND)

        self.plateMapSizer = wx.GridSizer(1,1,5,5)
        self.plateMaps = []
        self.plateMapChoices = []

        self.rightSizer = wx.BoxSizer(wx.VERTICAL)
        self.rightSizer.Add(self.plateMapSizer, 1, wx.EXPAND|wx.BOTTOM, 10)
        self.colorBar = ColorBarPanel(self, 'jet', size=(-1,25))
        self.rightSizer.Add(self.colorBar, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL)

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(controlSizer, 0, wx.LEFT|wx.TOP|wx.BOTTOM, 10)
        mainSizer.Add(self.rightSizer, 1, wx.EXPAND|wx.ALL, 10)

        self.SetSizer(mainSizer)
        self.SetClientSize((self.Size[0],self.Sizer.CalcMin()[1]))

        self.sourceChoice.Bind(wx.EVT_COMBOBOX, self.UpdateMeasurementChoice)
        self.measurementsChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectMeasurement)
        self.measurementsChoice.Select(0)
        self.aggregationMethodsChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectAggregationMethod)
        self.colorMapsChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectColorMap)
        self.numberOfPlatesTE.Bind(wx.EVT_TEXT_ENTER, self.OnEnterNumberOfPlates)
        self.wellDisplayChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectWellDisplay)
        self.annotationCol.Bind(wx.EVT_COMBOBOX, self.OnSelectAnnotationCol)
        self.addAnnotationColBtn.Bind(wx.EVT_BUTTON, self.OnAddAnnotationCol)
        self.annotationLabel.Bind(wx.EVT_KEY_UP, self.OnEnterAnnotation)
        self.outlineMarked.Bind(wx.EVT_CHECKBOX, self.OnOutlineMarked)
        self.annotationShowVals.Bind(wx.EVT_CHECKBOX, self.OnShowAnnotationValues)
        self.filterChoice.Bind(wx.EVT_COMBOBOX, self.OnSelectFilter)

        self.AddPlateMap()
        self.OnSelectMeasurement()
class PlotControl(wx.Panel):
    '''
    Control panel for the dimensionality reduction analysis
    '''
    def __init__(self, parent, fig_sco, fig_load, **kwargs):
        wx.Panel.__init__(self, parent, **kwargs)
        self.fig_sco = fig_sco
        self.fig_load = fig_load
        sizer = wx.BoxSizer(wx.VERTICAL)

        self.method_choice = ComboBox(self,
                                      -1,
                                      choices=[SVD, TSNE],
                                      style=wx.CB_READONLY)
        self.method_choice.Select(0)
        self.update_chart_btn = wx.Button(self, -1, "Show plot")
        self.help_btn = wx.Button(self, -1, "About")

        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.StaticText(self, -1, "Method:"))
        sz.AddSpacer((5, -1))
        sz.Add(self.method_choice, 1, wx.EXPAND)
        sizer.Add(sz, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 5))

        sz2 = wx.BoxSizer(wx.HORIZONTAL)
        sz2.Add(self.help_btn, wx.LEFT)
        sz2.AddSpacer((400, -1))
        sz2.Add(self.update_chart_btn, wx.RIGHT)

        sizer.Add(sz2, 1, wx.EXPAND)
        sizer.AddSpacer((-1, 5))

        wx.EVT_BUTTON(self.update_chart_btn, -1, self.on_show_pressed)
        wx.EVT_BUTTON(self.help_btn, -1, self.on_show_about)

        self.SetSizer(sizer)
        self.Show(1)

    def on_show_about(self, evt):
        '''
        Shows a message box with the version number etc.
        '''
        message = (
            'Dimensionality Reduction Plot was developed at the Intelligent Systems Dept., '
            'Radboud Universiteit Nijmegen as part of the CellProfiler project and is'
            ' distributed under the GNU General Public License version 2.\n'
            '\n'
            'For more information about the dimensionality reduction algorithms check:\n'
            '\n'
            '*Singular Value Decomposition: http://www.snl.salk.edu/~shlens/pca.pdf\n'
            '\n'
            '*t-SNE: http://homepage.tudelft.nl/19j49/t-SNE.html\n')
        dlg = wx.MessageDialog(self,
                               message,
                               'CellProfiler Analyst 2.0',
                               style=wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()

    def on_show_pressed(self, evt):
        '''
        Show the selected dimensionality reduction plot on the canvas      
        '''
        selected_method = self.method_choice.GetStringSelection()

        if selected_method == SVD:
            self.fig_sco.plot_pca()
            self.fig_load.plot_pca()
        elif selected_method == TSNE:
            self.fig_sco.plot_tsne()
            self.fig_load.clean_canvas()