class BoxPlotPanel(FigureCanvasWxAgg):
    def __init__(self, parent, points, **kwargs):
        '''
        points -- a dictionary mapping x axis values to lists of values to plot
        '''
        self.figure = Figure()
        FigureCanvasWxAgg.__init__(self, parent, -1, self.figure, **kwargs)
        self.canvas = self.figure.canvas
        self.SetMinSize((100,100))
        self.figure.set_facecolor((1,1,1))
        self.figure.set_edgecolor((1,1,1))
        self.canvas.SetBackgroundColour('white')
        
        self.navtoolbar = None
        self.setpoints(points)
        
    def setpoints(self, points):
        '''
        Updates the data to be plotted and redraws the plot.
        points - list of array samples, where each sample will be plotted as a 
                 separate box plot against the same y axis
        '''
        self.xlabels = []
        self.points = []
        ignored = 0
        for label, values in sorted(points.items()):
            if type(label) in [tuple, list]:
                self.xlabels += [','.join([str(l) for l in label])]
            else:
                self.xlabels += [label]
            self.points += [np.array(values).astype('f')[~ np.isnan(values)]]
            ignored += len(np.array(values)[np.isnan(values)])
        
        if not hasattr(self, 'subplot'):
            self.subplot = self.figure.add_subplot(111)
        self.subplot.clear()
        # nothing to plot?
        if len(self.points)==0:
            logging.warn('No data to plot.')
            return
        self.subplot.boxplot(self.points, sym='k.')
        if len(self.points) > 1:
            self.figure.autofmt_xdate()
        self.subplot.set_xticklabels(self.xlabels)
        self.reset_toolbar()
        if ignored == 0:
            logging.info('Boxplot: Plotted %s points.'%(sum(map(len, self.points))))
        else:
            logging.warn('Boxplot: Plotted %s points. Ignored %s NaNs.'
                          %(sum(map(len, self.points)), ignored))
        
    def set_x_axis_label(self, label):
        self.subplot.set_xlabel(label)
    
    def set_y_axis_label(self, label):
        self.subplot.set_ylabel(label)
    
    def get_point_lists(self):
        return self.points
    
    def get_xlabels(self):
        return self.xlabels
    
    def get_toolbar(self):
        if not self.navtoolbar:
            self.navtoolbar = NavigationToolbar(self.canvas)
            self.navtoolbar.DeleteToolByPos(6)
        return self.navtoolbar

    def reset_toolbar(self):
        # Cheat since there is no way reset
        if self.navtoolbar:
            self.navtoolbar._nav_stack.clear()
            self.navtoolbar.push_current()
Esempio n. 2
0
class DensityPanel(FigureCanvasWxAgg):
    def __init__(self, parent, **kwargs):
        self.figure = Figure()
        FigureCanvasWxAgg.__init__(self, parent, -1, self.figure, **kwargs)
        self.canvas = self.figure.canvas
        self.SetMinSize((100, 100))
        self.figure.set_facecolor((1, 1, 1))
        self.figure.set_edgecolor((1, 1, 1))
        self.canvas.SetBackgroundColour('white')
        self.subplot = self.figure.add_subplot(111)
        self.gate_helper = GatingHelper(self.subplot, self)

        self.navtoolbar = None
        self.point_list = []
        self.gridsize = 50
        self.cb = None
        self.x_scale = LINEAR_SCALE
        self.y_scale = LINEAR_SCALE
        self.color_scale = None
        self.x_label = ''
        self.y_label = ''
        self.cmap = 'jet'

        self.canvas.mpl_connect('button_release_event', self.on_release)

    def setpointslists(self, points):
        self.subplot.clear()
        self.point_list = points
        plot_pts = np.array(points).astype(float)

        if self.x_scale == LOG_SCALE:
            plot_pts = plot_pts[(plot_pts[:, 0] > 0)]
        if self.y_scale == LOG_SCALE:
            plot_pts = plot_pts[(plot_pts[:, 1] > 0)]

        hb = self.subplot.hexbin(plot_pts[:, 0],
                                 plot_pts[:, 1],
                                 gridsize=self.gridsize,
                                 xscale=self.x_scale,
                                 yscale=self.y_scale,
                                 bins=self.color_scale,
                                 cmap=matplotlib.cm.get_cmap(self.cmap))

        if self.cb:
            # Remove the existing colorbar and reclaim the space so when we add
            # a colorbar to the new hexbin subplot, it doesn't get indented.
            self.figure.delaxes(self.figure.axes[1])
            self.figure.subplots_adjust(right=0.90)
        self.cb = self.figure.colorbar(hb)
        if self.color_scale == LOG_SCALE:
            self.cb.set_label('log10(N)')

        self.subplot.set_xlabel(self.x_label)
        self.subplot.set_ylabel(self.y_label)

        xmin = np.nanmin(plot_pts[:, 0])
        xmax = np.nanmax(plot_pts[:, 0])
        ymin = np.nanmin(plot_pts[:, 1])
        ymax = np.nanmax(plot_pts[:, 1])

        # Pad all sides
        if self.x_scale == LOG_SCALE:
            xmin = xmin / 1.5
            xmax = xmax * 1.5
        else:
            xmin = xmin - (xmax - xmin) / 20.
            xmax = xmax + (xmax - xmin) / 20.

        if self.y_scale == LOG_SCALE:
            ymin = ymin / 1.5
            ymax = ymax * 1.5
        else:
            ymin = ymin - (ymax - ymin) / 20.
            ymax = ymax + (ymax - ymin) / 20.

        self.subplot.axis([xmin, xmax, ymin, ymax])

        self.reset_toolbar()

    def getpointslists(self):
        return self.point_list

    def setgridsize(self, gridsize):
        self.gridsize = gridsize

    def set_x_scale(self, scale):
        self.x_scale = scale

    def set_y_scale(self, scale):
        self.y_scale = scale

    def set_color_scale(self, scale):
        if scale == LINEAR_SCALE:
            scale = None
        self.color_scale = scale

    def set_x_label(self, label):
        self.x_label = label

    def set_y_label(self, label):
        self.y_label = label

    def set_colormap(self, cmap):
        self.cmap = cmap
        self.draw()

    def get_toolbar(self):
        if not self.navtoolbar:
            self.navtoolbar = NavigationToolbar(self.canvas)
        return self.navtoolbar

    def reset_toolbar(self):
        # Cheat since there is no way reset
        if self.navtoolbar:
            self.navtoolbar._views.clear()
            self.navtoolbar._positions.clear()
            self.navtoolbar.push_current()

    def set_configpanel(self, configpanel):
        '''Allow access of the control panel from the plotting panel'''
        self.configpanel = configpanel

    def on_release(self, evt):
        if evt.button == 3:  # right click
            self.show_popup_menu((evt.x, self.canvas.GetSize()[1] - evt.y),
                                 None)

    def show_popup_menu(self, (x, y), data):
        self.popup_menu_filters = {}
        popup = wx.Menu()
        loadimages_table_item = popup.Append(
            -1, 'Create gated table for CellProfiler LoadImages')
        selected_gate = self.configpanel.gate_choice.get_gatename_or_none()
        selected_gates = []
        if selected_gate:
            selected_gates = [selected_gate]
        self.Bind(
            wx.EVT_MENU, lambda (e): ui.prompt_user_to_create_loadimages_table(
                self, selected_gates), loadimages_table_item)

        show_images_in_gate_item = popup.Append(-1, 'Show images in gate')
        show_images_in_gate_item.Enable(selected_gate is not None)
        self.Bind(wx.EVT_MENU, self.show_images_from_gate,
                  show_images_in_gate_item)
        if p.object_table:
            show_objects_in_gate_item = popup.Append(
                -1, 'Show %s in gate' % (p.object_name[1]))
            show_objects_in_gate_item.Enable(selected_gate is not None)
            self.Bind(wx.EVT_MENU, self.show_objects_from_gate,
                      show_objects_in_gate_item)

        self.PopupMenu(popup, (x, y))
Esempio n. 3
0
class HistogramPanel(FigureCanvasWxAgg):
    def __init__(self, parent, points, bins=100, **kwargs):
        self.figure = Figure()
        FigureCanvasWxAgg.__init__(self, parent, -1, self.figure, **kwargs)
        self.canvas = self.figure.canvas
        self.SetMinSize((100, 100))
        self.figure.set_facecolor((1, 1, 1))
        self.figure.set_edgecolor((1, 1, 1))
        self.canvas.SetBackgroundColour('white')
        self.subplot = self.figure.add_subplot(111)
        self.gate_helper = GatingHelper(self.subplot, self)

        self.navtoolbar = NavigationToolbar(self.canvas)
        #self.navtoolbar.Realize()

        self.x_label = ''
        self.log_y = False
        self.x_scale = LINEAR_SCALE
        self.setpoints(points, bins)

        self.canvas.mpl_connect('button_release_event', self.on_release)

    def setpoints(self, points, bins):
        ''' Updates the data to be plotted and redraws the plot.
        points - array of samples
        bins - number of bins to aggregate points in
        '''
        points = np.array(points).astype('f')
        self.bins = bins
        x_label = self.x_label

        self.subplot.clear()
        # log xform the data, ignoring non-positives
        # XXX: This will not work for selection since the data is changed
        if self.x_scale in [LOG_SCALE, LOG2_SCALE]:
            if self.x_scale == LOG_SCALE:
                points = np.log(points[points > 0])
                x_label = 'Log(%s)' % (self.x_label)
            elif self.x_scale == LOG2_SCALE:
                points = np.log2(points[points > 0])
                x_label = 'Log2(%s)' % (self.x_label)
            ignored = len(points[points <= 0])
            if ignored > 0:
                logging.warn('Histogram ignored %s negative value%s.' %
                             (ignored, (ignored != 1 and 's' or '')))

        # hist apparently doesn't like nans, need to preen them out first
        points = points[~np.isnan(points)]

        # nothing to plot?
        if len(points) == 0:
            logging.warn('No data to plot.')
            return

        self.subplot.hist(points,
                          self.bins,
                          facecolor=[0.0, 0.62, 1.0],
                          edgecolor='none',
                          log=self.log_y,
                          alpha=0.75)
        self.subplot.set_xlabel(x_label)
        self.reset_toolbar()

    def set_x_label(self, label):
        self.x_label = label

    def set_x_scale(self, scale):
        '''scale -- LINEAR_SCALE, LOG_SCALE, or LOG2_SCALE'''
        self.x_scale = scale

    def set_y_scale(self, scale):
        '''scale -- LINEAR_SCALE or LOG_SCALE'''
        if scale == LINEAR_SCALE:
            self.log_y = False
        elif scale == LOG_SCALE:
            self.log_y = True
        else:
            raise ValueError('Unsupported y-axis scale.')

    def get_toolbar(self):
        return self.navtoolbar

    def reset_toolbar(self):
        '''Clears the navigation toolbar history. Called after setpoints.'''
        # Cheat since there is no way reset
        if self.navtoolbar:
            self.navtoolbar._views.clear()
            self.navtoolbar._positions.clear()
            self.navtoolbar.push_current()

    def set_configpanel(self, configpanel):
        '''Allow access of the control panel from the plotting panel'''
        self.configpanel = configpanel

    def on_release(self, evt):
        '''click handler'''
        if evt.button == 3:  # right click
            self.show_popup_menu((evt.x, self.canvas.GetSize()[1] - evt.y),
                                 None)

    def show_popup_menu(self, (x, y), data):
        '''Show context sensitive popup menu.'''
        self.popup_menu_filters = {}
        popup = wx.Menu()
        loadimages_table_item = popup.Append(
            -1, 'Create gated table for CellProfiler LoadImages')
        selected_gate = self.configpanel.gate_choice.get_gatename_or_none()
        selected_gates = []
        if selected_gate:
            selected_gates = [selected_gate]
        self.Bind(
            wx.EVT_MENU, lambda (e): ui.prompt_user_to_create_loadimages_table(
                self, selected_gates), loadimages_table_item)

        show_images_in_gate_item = popup.Append(-1, 'Show images in gate')
        show_images_in_gate_item.Enable(selected_gate is not None)
        self.Bind(wx.EVT_MENU, self.show_images_from_gate,
                  show_images_in_gate_item)
        if p.object_table:
            show_objects_in_gate_item = popup.Append(
                -1, 'Show %s in gate (montage)' % (p.object_name[1]))
            show_objects_in_gate_item.Enable(selected_gate is not None)
            self.Bind(wx.EVT_MENU, self.show_objects_from_gate,
                      show_objects_in_gate_item)

        self.PopupMenu(popup, (x, y))