def view_pair(self, p, table_positive): fig1 = new_figure(300,300) axes.kde2d_color_hist(fig1, table_positive, (p[0], p[1]), None, None, 0.001) fig = new_figure(300,300) axes.kde2d_color_hist(fig, table_positive, (p[0], p[1]), None, 'y', 0.001) #ax_dis = new_axes(300,300) dis_points = find_discontinuities(table_positive, p[0], p[1], None) return stack_lines( self.widgets.kde2d_fig.view(fig1), self.widgets.kde2d_fig.view(fig), # self.widgets.kde2d_fig.view(ax_dis.figure), dis_points, self.widgets.pair_fit_split.view(table_positive, p[0], p[1]))
def view_pair(self, p, table_positive): fig1 = new_figure(300, 300) axes.kde2d_color_hist(fig1, table_positive, (p[0], p[1]), None, None, 0.001) fig = new_figure(300, 300) axes.kde2d_color_hist(fig, table_positive, (p[0], p[1]), None, 'y', 0.001) #ax_dis = new_axes(300,300) dis_points = find_discontinuities(table_positive, p[0], p[1], None) return stack_lines( self.widgets.kde2d_fig.view(fig1), self.widgets.kde2d_fig.view(fig), # self.widgets.kde2d_fig.view(ax_dis.figure), dis_points, self.widgets.pair_fit_split.view(table_positive, p[0], p[1]))
def view(self, pairs, table, mi_table=None): lines = [] logging.info('Creating pairtable for %d pairs...' % len(pairs)) timer = MultiTimer(len(pairs)) for p in pairs: gc.collect() line = [] line.append(p[0]) line.append(p[1]) if mi_table: i1 = mi_table.dims.index(p[0]) i2 = mi_table.dims.index(p[1]) line.append(mi_table.data[i1, i2]) else: line.append('') table_positive = table.remove_bad_cells(p[0], p[1]) #table_positive = table print ' (%d cells)' % table_positive.num_cells if table_positive.num_cells > 100: fig = new_figure(300,300) axes.kde2d_color_hist(fig, table_positive, (p[0], p[1]), None, 'y', 0.001) #ax_dis = new_axes(300,300) dis_points = find_discontinuities(table_positive, p[0], p[1], None) line.append(self.view_pair(p, table_positive)) line.append(self.view_pair((p[1], p[0]), table_positive)) ax = new_axes(300,300) axes.scatter(ax, table_positive, (p[0], p[1]), norm_axis=None, no_bins=300j) line.append(self.widgets.kde2d_fig.view(ax.figure)) lines.append(line) timer.complete_task('%s, %s' % tuple(p[:2])) return self.widgets.table.view( ['Dimension 1', 'Dimension 2', 'Mutual Information', 'Normalized Plot1','Normalized Plot2','Scatter Plot'], lines, None, [('Mutual Information', 'desc')])
def _draw_figures_internal(self, table, dim_x, dim_y, range): fig = axes.new_figure(FIG_SIZE_X, FIG_SIZE_Y) try: axes.kde2d_color_hist(fig, table, (dim_x, dim_y), range) return {'fig': fig} except Exception as e: logging.exception('Exception in DensityPlot') return {'fig': (None, View(self, str(e)))}
def view(self): #cluster = 'B-cells CD20+' cluster = 'Progenitor cells CD38+' stim = 'PVO4' #'All' index = DataIndex.load(r'c:\cytof54_clustered\cytof54.index') t = index.load_table(cluster_name=cluster, stim=stim) dims = t.get_markers('signal') width = 800 height = 800 left_space = 80. / width top_space = 80. / height sub_width = (1. - left_space) / len(dims) sub_height = (1. - top_space) / len(dims) fig = new_figure(width, height) for i in xrange(len(dims)): y_pos = 1 - sub_height - top_space - i * sub_height x_pos = 0 ax = fig.add_axes((x_pos, y_pos, left_space, sub_height)) ax.text(0.5, 0.5, dims[i], fontsize='xx-small', rotation='horizontal', horizontalalignment='center', verticalalignment='center', transform=ax.transAxes) axes.remove_ticks(ax) for j in xrange(len(dims)): y_pos = 1 - top_space x_pos = left_space + j * sub_width ax = fig.add_axes((x_pos, y_pos, sub_width, top_space)) ax.text(0.5, 0.5, dims[j], fontsize='xx-small', rotation='vertical', horizontalalignment='center', verticalalignment='center', transform=ax.transAxes) axes.remove_ticks(ax) timer = MultiTimer(len(dims)**2 - len(dims)) for i in xrange(len(dims)): for j in xrange(len(dims)): if i == j: continue dim1 = dims[i] dim2 = dims[j] table_positive = t.remove_bad_cells(dim1, dim2) y_pos = 1 - sub_height - top_space - i * sub_height x_pos = left_space + j * sub_width ax = fig.add_axes((x_pos, y_pos, sub_width, sub_height), axisbg=cm.jet(0)) #print '' #print (x_pos,y_pos, sub_width, sub_height) axes.kde2d(ax, table_positive, (dim1, dim2), None, 'y', 0.001) axes.remove_ticks(ax) timer.complete_task('%s, %s' % (dim1, dim2)) return self.widgets.kde2d_fig.view(fig)
def _draw_figures_internal(self, table, dim_x, dim_y, range): fig = axes.new_figure(FIG_SIZE_X, FIG_SIZE_Y) try: axes.kde2d_color_hist(fig, table, (dim_x, dim_y), range, 'y', self.widgets.min_density_in_column.value_as_float()) corr_view = View(None, 'corr: %.2f; mi: %.2f' % (table.get_correlation(dim_x, dim_y), table.get_mutual_information(dim_x, dim_y))) return {'fig': (fig, corr_view)} except Exception as e: logging.exception('Exception in DensityPlot') return {'fig': (None, View(self, str(e)))}
def _draw_figures_internal(self, table, dim_x, dim_y, range): res = float(self.widgets.resolution.get_choice()) ax_width, ax_height = self.get_planned_axes_width() ax_width /= res ax_height /= res if res == 1: interpolation = 'nearest' else: interpolation = 'blackman' colors = self.widgets.color.values.choices min_cells = int(self.widgets.min_cells_in_bin.values.value) - 1 ret = OrderedDict() for color in colors: try: if color == 'none': color = None fig = axes.new_figure(FIG_SIZE_X, FIG_SIZE_Y) ax = fig.add_subplot(111) hist, extent = axes.histogram_scatter( ax, table, (dim_x, dim_y), range, color, min_cells_per_bin=min_cells, no_bins_x=ax_width * 1j, no_bins_y=ax_height * 1j, interpolation=interpolation) if self.widgets.contour.get_choices()[0] == 'regular': cs = ax.contour(hist, extent=extent, origin='lower') #ax.clabel(cs, inline=1, fontsize=10) elif self.widgets.contour.get_choices()[0] == 'smooth': display_data, extent, density, X, Y = axes.kde2d_data( table, (dim_x, dim_y), range, res=ax_width) #np.r_[0:np.max(display_data):10j][1:] levels = np.array([ 0.1, 0.2, 0.3, 0.35, 0.4, 0.5, 0.6, 0.8, 1 ]) * np.max(display_data) if color != None: cs = ax.contour(display_data, extent=extent, origin='lower', levels=levels, colors='black') else: cs = ax.contour(display_data, extent=extent, origin='lower', levels=levels) #ax.clabel(cs, inline=1, fontsize=10) ret[str(color)] = fig except Exception as e: logging.exception('Exception in ScatterPlot') ret[str(color)] = (None, View(self, str(e))) return ret
def view(self): #cluster = 'B-cells CD20+' cluster = 'Progenitor cells CD38+' stim='PVO4' #'All' index = DataIndex.load(r'c:\cytof54_clustered\cytof54.index') t = index.load_table(cluster_name=cluster, stim=stim) dims = t.get_markers('signal') width = 800 height = 800 left_space = 80./width top_space = 80./height sub_width = (1. - left_space) / len(dims) sub_height =(1. - top_space) / len(dims) fig = new_figure(width, height) for i in xrange(len(dims)): y_pos = 1 - sub_height - top_space - i * sub_height x_pos = 0 ax = fig.add_axes((x_pos,y_pos, left_space, sub_height)) ax.text( 0.5, 0.5,dims[i], fontsize='xx-small', rotation='horizontal', horizontalalignment='center', verticalalignment='center', transform = ax.transAxes) axes.remove_ticks(ax) for j in xrange(len(dims)): y_pos = 1 - top_space x_pos = left_space + j * sub_width ax = fig.add_axes((x_pos,y_pos, sub_width, top_space)) ax.text( 0.5, 0.5,dims[j], fontsize='xx-small', rotation='vertical', horizontalalignment='center', verticalalignment='center', transform = ax.transAxes) axes.remove_ticks(ax) timer = MultiTimer(len(dims)**2 - len(dims)) for i in xrange(len(dims)): for j in xrange(len(dims)): if i==j: continue dim1 = dims[i] dim2 = dims[j] table_positive = t.remove_bad_cells(dim1, dim2) y_pos = 1 - sub_height - top_space - i * sub_height x_pos = left_space + j * sub_width ax = fig.add_axes((x_pos,y_pos, sub_width, sub_height), axisbg=cm.jet(0)) #print '' #print (x_pos,y_pos, sub_width, sub_height) axes.kde2d( ax, table_positive, (dim1, dim2), None, 'y', 0.001) axes.remove_ticks(ax) timer.complete_task('%s, %s' % (dim1,dim2)) return self.widgets.kde2d_fig.view(fig)
def get_planned_axes_width(self): # We need to calculate the pixel size for the figure # so we create a fake figure and add to it a colorbar # and axes the same way the scatter function sdoes: fig = axes.new_figure(FIG_SIZE_X, FIG_SIZE_Y) ax = fig.add_subplot(111) ax.set_xlabel('temp', size='x-small') ax.set_ylabel('temp', size='x-small') ax.figure.subplots_adjust(bottom=0.15) cbar = ax.figure.colorbar(ax.imshow([[0]])) # Now we know the future width, height. return axes.ax_size_pixels(ax)
def _draw_figures_internal(self, table, dim_x, dim_y, range): ret = OrderedDict(); try: if table.num_cells > 10000: raise Exception('table is too big') fig = axes.new_figure(FIG_SIZE_X, FIG_SIZE_Y) ax = fig.add_subplot(111) axes.points(ax, table, (dim_x, dim_y), range) ret[0] = fig; except Exception as e: logging.exception('Exception in ScatterPlot') ret[0] = (None, View(self, str(e))) return ret
def _draw_figures_internal(self, table, dim_x, dim_y, range): fig = axes.new_figure(FIG_SIZE_X, FIG_SIZE_Y) try: axes.kde2d_color_hist( fig, table, (dim_x, dim_y), range, 'y', self.widgets.min_density_in_column.value_as_float()) corr_view = View( None, 'corr: %.2f; mi: %.2f' % (table.get_correlation( dim_x, dim_y), table.get_mutual_information(dim_x, dim_y))) return {'fig': (fig, corr_view)} except Exception as e: logging.exception('Exception in DensityPlot') return {'fig': (None, View(self, str(e)))}
def _draw_figures_internal(self, table, dim_x, dim_y, range): ret = OrderedDict() try: if table.num_cells > 10000: raise Exception('table is too big') fig = axes.new_figure(FIG_SIZE_X, FIG_SIZE_Y) ax = fig.add_subplot(111) axes.points(ax, table, (dim_x, dim_y), range) ret[0] = fig except Exception as e: logging.exception('Exception in ScatterPlot') ret[0] = (None, View(self, str(e))) return ret
def create_and_adjust_figure(self, tables): X_SIZE_FOR_HISTOGRAMS = 300 X_SIZE_PER_NAME_LETTER = 6 Y_SIZE_PER_CURVE = 35 MIN_Y = 300 # first let's calculate the width. texts = [str(t.get_tags(self.widgets.text.values.choices)) for t in tables] max_text_length = max([len(t) for t in texts]) x_size_for_text = X_SIZE_PER_NAME_LETTER * max_text_length x_size = x_size_for_text + X_SIZE_FOR_HISTOGRAMS y_size = len(tables) * Y_SIZE_PER_CURVE y_size = max(MIN_Y, y_size) fig = axes.new_figure(x_size, y_size) fig.subplots_adjust(left=x_size_for_text / float(x_size)) return fig
def create_and_adjust_figure(self, tables): X_SIZE_FOR_HISTOGRAMS = 300 X_SIZE_PER_NAME_LETTER = 6 Y_SIZE_PER_CURVE = 35 MIN_Y = 300 # first let's calculate the width. texts = [ str(t.get_tags(self.widgets.text.values.choices)) for t in tables ] max_text_length = max([len(t) for t in texts]) x_size_for_text = X_SIZE_PER_NAME_LETTER * max_text_length x_size = x_size_for_text + X_SIZE_FOR_HISTOGRAMS y_size = len(tables) * Y_SIZE_PER_CURVE y_size = max(MIN_Y, y_size) fig = axes.new_figure(x_size, y_size) fig.subplots_adjust(left=x_size_for_text / float(x_size)) return fig
def _draw_figures_internal(self, table, dim_x, dim_y, range): res = float(self.widgets.resolution.get_choice()) ax_width, ax_height = self.get_planned_axes_width() ax_width /= res ax_height /= res if res == 1: interpolation = 'nearest' else: interpolation = 'blackman' colors = self.widgets.color.values.choices min_cells = int(self.widgets.min_cells_in_bin.values.value)-1 ret = OrderedDict() for color in colors: try: if color == 'none': color = None fig = axes.new_figure(FIG_SIZE_X, FIG_SIZE_Y) ax = fig.add_subplot(111) hist, extent = axes.histogram_scatter(ax, table, (dim_x, dim_y), range, color, min_cells_per_bin = min_cells, no_bins_x=ax_width*1j, no_bins_y=ax_height*1j, interpolation=interpolation) if self.widgets.contour.get_choices()[0] == 'regular': cs = ax.contour(hist, extent=extent, origin='lower') #ax.clabel(cs, inline=1, fontsize=10) elif self.widgets.contour.get_choices()[0] == 'smooth': display_data, extent, density, X, Y = axes.kde2d_data(table, (dim_x, dim_y), range, res=ax_width) #np.r_[0:np.max(display_data):10j][1:] levels = np.array([0.1, 0.2, 0.3, 0.35, 0.4, 0.5, 0.6, 0.8, 1]) * np.max(display_data) if color!=None: cs = ax.contour(display_data, extent=extent, origin='lower', levels=levels, colors='black') else: cs = ax.contour(display_data, extent=extent, origin='lower', levels=levels) #ax.clabel(cs, inline=1, fontsize=10) ret[str(color)] = fig except Exception as e: logging.exception('Exception in ScatterPlot') ret[str(color)] = (None, View(self, str(e))) return ret
def view(self, pairs, table, mi_table=None): lines = [] logging.info('Creating pairtable for %d pairs...' % len(pairs)) timer = MultiTimer(len(pairs)) for p in pairs: gc.collect() line = [] line.append(p[0]) line.append(p[1]) if mi_table: i1 = mi_table.dims.index(p[0]) i2 = mi_table.dims.index(p[1]) line.append(mi_table.data[i1, i2]) else: line.append('') table_positive = table.remove_bad_cells(p[0], p[1]) #table_positive = table print ' (%d cells)' % table_positive.num_cells if table_positive.num_cells > 100: fig = new_figure(300, 300) axes.kde2d_color_hist(fig, table_positive, (p[0], p[1]), None, 'y', 0.001) #ax_dis = new_axes(300,300) dis_points = find_discontinuities(table_positive, p[0], p[1], None) line.append(self.view_pair(p, table_positive)) line.append(self.view_pair((p[1], p[0]), table_positive)) ax = new_axes(300, 300) axes.scatter(ax, table_positive, (p[0], p[1]), norm_axis=None, no_bins=300j) line.append(self.widgets.kde2d_fig.view(ax.figure)) lines.append(line) timer.complete_task('%s, %s' % tuple(p[:2])) return self.widgets.table.view([ 'Dimension 1', 'Dimension 2', 'Mutual Information', 'Normalized Plot1', 'Normalized Plot2', 'Scatter Plot' ], lines, None, [('Mutual Information', 'desc')])
def view(self, tables): """ The view method of this module draws the control panel and the histograms. We need at least one input to be able to draw something. """ if not tables: return View(self, 'No tables to show.') self.widgets.color.guess_or_remember(('histogram text', tables), ['name']) self.widgets.text.guess_or_remember(('histogram colors', tables), ['name']) self.widgets.shift.guess_or_remember(('histogram shift', tables), '0.2') self.widgets.sort_inside.guess_or_remember(('histogram sort inside', tables), ['similarity']) self.widgets.sort_outside.guess_or_remember(('histogram sort outside', tables), ['sort']) self.widgets.trim.guess_or_remember(('histogram trim', tables), ['no']) self.widgets.trim_thresh.guess_or_remember(('histogram trim thresh', tables), '0') sort_inside_options = [('unsort', 'Keep original order'), ('similarity', 'Put similar curves together')] sort_inside_options += [(x, 'Sort by %s' % x) for x in tables[0].tags.keys()] # Create the control panel view. This will enable users to choose the dimensions. control_panel_view = stack_lines( self.widgets.dims.view('Dimension', self.widgets.apply, options_from_table(tables[0])), self.widgets.text.view('Text by', self.widgets.apply, tables[0].tags.keys()), self.widgets.color.view('Color by', self.widgets.apply, tables[0].tags.keys()), self.widgets.shift.view('Shift for multiple curves', self.widgets.apply), self.widgets.sort_inside.view('Curve sorting', self.widgets.apply, sort_inside_options, multiple=False), self.widgets.sort_outside.view('Plot sorting', self.widgets.apply, [('sort', 'Put plots with many differences first'), ('unsort', 'Keep original order')], multiple=False), self.widgets.trim.view('Trim plots', self.widgets.apply, [('yes', 'Convert values lower than threshold to 0'), ('no', 'Don\'t trim')], multiple=False), self.widgets.trim_thresh.view('Trim threshold', self.widgets.apply), self.widgets.apply.view()) main_views = [] shift = self.widgets.shift.value_as_float() plots_for_legend = OrderedDict() colorer = axes.Colorer() # Check that the user has already chosen dimensions. Otherwise, ask him # to do so. if self.widgets.dims.values.choices: timer = MultiTimer(len(self.widgets.dims.values.choices)) for i, dim in enumerate(self.widgets.dims.values.choices): try: # Go over every dimension and create the histogram: # First create a new figure: fig = self.create_and_adjust_figure(tables) ax = fig.add_subplot(111) # Draw the histogram for every input plots = [] sorted_tables = tables sort_method = self.widgets.sort_inside.values.choices[0] if sort_method == 'unsort': sorted_tables = tables elif sort_method == 'similarity': thresh = None if self.widgets.trim.get_choices()[0] == 'yes': thresh = self.widgets.trim_thresh.value_as_float() # get distances table: distances = datatable.ks_distances(tables, dim, thresh) # sort by distance sorted_tables = greedy_distance_sort(distances, tables) else: # we need to sort by tags: tag_for_sort = self.widgets.sort_inside.values.choices[0] sorted_tables = sorted(tables, key=lambda table: table.tags[tag_for_sort]) for i, table in enumerate(sorted_tables): color_tags = self.widgets.color.values.choices color_key = tuple([table.tags[c] for c in color_tags]) min_x = None if self.widgets.trim.get_choices()[0] =='yes': min_x = self.widgets.trim_thresh.value_as_float() plot = axes.kde1d(ax, table, dim, color=colorer.get_color(color_key), min_x=min_x, shift=shift*i) plots_for_legend[color_key] = plot # Add ticks with table names: if self.widgets.shift.value_as_float() > 0: ax.set_yticks(np.arange(0, len(tables)*shift, shift)) ax.set_yticklabels([t.get_tags(self.widgets.text.values.choices) for t in sorted_tables], size='xx-small') # set axes y range: ax.set_ylim(bottom = -0.1, top=0.8+shift*(len(sorted_tables)-1)) # Make sure we don't create the same widget twice. We create a new widget # for every dimension asked. widget_key = self._normalize_id(dim) if not widget_key in self.widgets: self._add_widget(widget_key, Figure) figure_widget = self.widgets[widget_key] if len(tables) > 1: from scipy.stats import ks_2samp ks, p_ks = ks_2samp(tables[0].get_cols(dim)[0], tables[1].get_cols(dim)[0]) ks_view = View(self, 'ks: %.3f, p_ks: %.10f' % (ks, p_ks)) final_view = stack_lines(ks_view, figure_widget.view(fig)) else: ks, p_ks = 0, 0 final_view = figure_widget.view(fig) # Add the new widget's view main_views.append((ks, p_ks, final_view)) except Exception as e: logging.exception('Exception when drawing histogram') main_views.append((0, 0, View(self, str(e)))) timer.complete_task(dim) # sort by the ks test: main_views = sorted(main_views, key=itemgetter(0), reverse=True) main_views = [v[2] for v in main_views] # create legend: legened_titles = plots_for_legend.keys() print len(legened_titles) max_title_len = max([len(str(t)) for t in legened_titles] + [0]) print max_title_len WIDTH_PER_LETTER = 7 EXTRA_WIDTH = 60 HEIGHT_PER_LINE = 30 EXTRA_HEIGHT = 50 MIN_X = 300 MIN_Y = 100 legend_x = max(MIN_X, EXTRA_WIDTH + WIDTH_PER_LETTER * max_title_len) legend_y = max(MIN_Y, EXTRA_HEIGHT + HEIGHT_PER_LINE * len(legened_titles)) fig = axes.new_figure(legend_x, legend_y) ax = fig.add_subplot(111) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.legend(plots_for_legend.values(), plots_for_legend.keys(), loc='center', mode='expand', frameon=False, prop={'size' : 'xx-small'}) main_views = [self.widgets.legend_figure.view(fig)] + main_views main_view = view.stack_left(*main_views) else: main_view = View(None, 'Please select dimensions') # combine the control panel and the main view togeteher: return self.widgets.layout.view(main_view, control_panel_view)
def view(self, tables): """ The view method of this module draws the control panel and the histograms. We need at least one input to be able to draw something. """ if not tables: return View(self, 'No tables to show.') self.widgets.color.guess_or_remember(('histogram text', tables), ['name']) self.widgets.text.guess_or_remember(('histogram colors', tables), ['name']) self.widgets.shift.guess_or_remember(('histogram shift', tables), '0.2') self.widgets.sort_inside.guess_or_remember( ('histogram sort inside', tables), ['similarity']) self.widgets.sort_outside.guess_or_remember( ('histogram sort outside', tables), ['sort']) self.widgets.trim.guess_or_remember(('histogram trim', tables), ['no']) self.widgets.trim_thresh.guess_or_remember( ('histogram trim thresh', tables), '0') sort_inside_options = [('unsort', 'Keep original order'), ('similarity', 'Put similar curves together')] sort_inside_options += [(x, 'Sort by %s' % x) for x in tables[0].tags.keys()] # Create the control panel view. This will enable users to choose the dimensions. control_panel_view = stack_lines( self.widgets.dims.view('Dimension', self.widgets.apply, options_from_table(tables[0])), self.widgets.text.view('Text by', self.widgets.apply, tables[0].tags.keys()), self.widgets.color.view('Color by', self.widgets.apply, tables[0].tags.keys()), self.widgets.shift.view('Shift for multiple curves', self.widgets.apply), self.widgets.sort_inside.view('Curve sorting', self.widgets.apply, sort_inside_options, multiple=False), self.widgets.sort_outside.view( 'Plot sorting', self.widgets.apply, [('sort', 'Put plots with many differences first'), ('unsort', 'Keep original order')], multiple=False), self.widgets.trim.view( 'Trim plots', self.widgets.apply, [('yes', 'Convert values lower than threshold to 0'), ('no', 'Don\'t trim')], multiple=False), self.widgets.trim_thresh.view('Trim threshold', self.widgets.apply), self.widgets.apply.view()) main_views = [] shift = self.widgets.shift.value_as_float() plots_for_legend = OrderedDict() colorer = axes.Colorer() # Check that the user has already chosen dimensions. Otherwise, ask him # to do so. if self.widgets.dims.values.choices: timer = MultiTimer(len(self.widgets.dims.values.choices)) for i, dim in enumerate(self.widgets.dims.values.choices): try: # Go over every dimension and create the histogram: # First create a new figure: fig = self.create_and_adjust_figure(tables) ax = fig.add_subplot(111) # Draw the histogram for every input plots = [] sorted_tables = tables sort_method = self.widgets.sort_inside.values.choices[0] if sort_method == 'unsort': sorted_tables = tables elif sort_method == 'similarity': thresh = None if self.widgets.trim.get_choices()[0] == 'yes': thresh = self.widgets.trim_thresh.value_as_float() # get distances table: distances = datatable.ks_distances(tables, dim, thresh) # sort by distance sorted_tables = greedy_distance_sort(distances, tables) else: # we need to sort by tags: tag_for_sort = self.widgets.sort_inside.values.choices[ 0] sorted_tables = sorted( tables, key=lambda table: table.tags[tag_for_sort]) for i, table in enumerate(sorted_tables): color_tags = self.widgets.color.values.choices color_key = tuple([table.tags[c] for c in color_tags]) min_x = None if self.widgets.trim.get_choices()[0] == 'yes': min_x = self.widgets.trim_thresh.value_as_float() plot = axes.kde1d(ax, table, dim, color=colorer.get_color(color_key), min_x=min_x, shift=shift * i) plots_for_legend[color_key] = plot # Add ticks with table names: if self.widgets.shift.value_as_float() > 0: ax.set_yticks(np.arange(0, len(tables) * shift, shift)) ax.set_yticklabels([ t.get_tags(self.widgets.text.values.choices) for t in sorted_tables ], size='xx-small') # set axes y range: ax.set_ylim(bottom=-0.1, top=0.8 + shift * (len(sorted_tables) - 1)) # Make sure we don't create the same widget twice. We create a new widget # for every dimension asked. widget_key = self._normalize_id(dim) if not widget_key in self.widgets: self._add_widget(widget_key, Figure) figure_widget = self.widgets[widget_key] if len(tables) > 1: from scipy.stats import ks_2samp ks, p_ks = ks_2samp(tables[0].get_cols(dim)[0], tables[1].get_cols(dim)[0]) ks_view = View(self, 'ks: %.3f, p_ks: %.10f' % (ks, p_ks)) final_view = stack_lines(ks_view, figure_widget.view(fig)) else: ks, p_ks = 0, 0 final_view = figure_widget.view(fig) # Add the new widget's view main_views.append((ks, p_ks, final_view)) except Exception as e: logging.exception('Exception when drawing histogram') main_views.append((0, 0, View(self, str(e)))) timer.complete_task(dim) # sort by the ks test: main_views = sorted(main_views, key=itemgetter(0), reverse=True) main_views = [v[2] for v in main_views] # create legend: legened_titles = plots_for_legend.keys() print len(legened_titles) max_title_len = max([len(str(t)) for t in legened_titles] + [0]) print max_title_len WIDTH_PER_LETTER = 7 EXTRA_WIDTH = 60 HEIGHT_PER_LINE = 30 EXTRA_HEIGHT = 50 MIN_X = 300 MIN_Y = 100 legend_x = max(MIN_X, EXTRA_WIDTH + WIDTH_PER_LETTER * max_title_len) legend_y = max( MIN_Y, EXTRA_HEIGHT + HEIGHT_PER_LINE * len(legened_titles)) fig = axes.new_figure(legend_x, legend_y) ax = fig.add_subplot(111) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax.legend(plots_for_legend.values(), plots_for_legend.keys(), loc='center', mode='expand', frameon=False, prop={'size': 'xx-small'}) main_views = [self.widgets.legend_figure.view(fig)] + main_views main_view = view.stack_left(*main_views) else: main_view = View(None, 'Please select dimensions') # combine the control panel and the main view togeteher: return self.widgets.layout.view(main_view, control_panel_view)