def view(self, **tables): self.widgets.edge_stat.guess_or_remember((tables, 'Compare'), []) self.widgets.node_stat.guess_or_remember((tables, 'Compare'), []) NODE_STATS = ['values'] EDGE_STATS = [] control_panel_view = stack_lines( self.widgets.edge_stat.view('Edge statistics', self.widgets.apply, sorted(EDGE_STATS)), self.widgets.node_stat.view('Node statistics', self.widgets.apply, sorted(NODE_STATS)), self.widgets.apply.view()) data_tables = [t for t in tables.values() if t] networks = [n for n in self.widgets.network.values.choices if n in NETWORKS] main_views = [] for network in networks: nodes = set() edges = set() for graph_entry in NETWORKS[network]: nodes.add((graph_entry[0], node_label(graph_entry[0], data_tables, self.widgets.node_stat.values.choices), 0)) nodes.add((graph_entry[1], node_label(graph_entry[1], data_tables, self.widgets.node_stat.values.choices), 0)) edges.add((edge_label(graph_entry[0], graph_entry[1], data_tables, self.widgets.edge_stat.values.choices), 0, graph_entry[0], graph_entry[1], True)) main_views += [self._get_widget('graph_%s' % network).view(nodes, edges)] main_view = stack_left(*main_views) return self.widgets.layout.view(main_view, control_panel_view)
def view(self, apply_button, datatable): experiments = settings.EXPERIMENTS.keys() if not self.experiment: return stack_lines( self.widgets.experiment_select.view('Please Select an experiment', self.widgets.apply, experiments, False), self.widgets.apply.view()) if not self.experiment in self.experiment_to_widgets: index = self._get_index() widgets = [] if type(settings.EXPERIMENTS[self.experiment]) == tuple: editable_tags = settings.EXPERIMENTS[self.experiment][1] else: editable_tags = index.all_tags() for tag in editable_tags: new_widget = self._add_widget('%s_%s' % (self.experiment, tag), Select) new_widget.tag = tag new_widget.vals = index.all_values_for_tag(tag) widgets.append(new_widget) self.experiment_to_widgets[self.experiment] = widgets views = [w.view(w.tag, self.widgets.apply, w.vals) for w in self.experiment_to_widgets[self.experiment]] stacked_views = stack_left(*views) expanded = stack_lines( self.widgets.experiment_select.view( 'Experiment', self.widgets.apply, experiments, False), stacked_views, View(None, '<p style="clear: both"></p>'), self.widgets.apply.view()) #return expanded return self.widgets.expander.view('',[self.summary], [expanded])
def view(self, tables): global NETWORKS self.widgets.network.guess_or_remember((tables, 'Network'), []) self.widgets.edge_stat.guess_or_remember((tables, 'Network'), []) self.widgets.node_stat.guess_or_remember((tables, 'Network'), []) control_panel_view = stack_lines( self.widgets.network.view('Network', self.widgets.apply, sorted(NETWORKS.keys())), self.widgets.edge_stat.view('Edge statistic to show', self.widgets.apply, sorted(EDGE_STATS.keys())), self.widgets.node_stat.view('Node statistic to show', self.widgets.apply, sorted(NODE_STATS.keys())), self.widgets.apply.view()) networks = [n for n in self.widgets.network.values.choices if n in NETWORKS] main_views = [] for network in networks: nodes = set() edges = set() for graph_entry in NETWORKS[network]: nodes.add((graph_entry[0], node_label(graph_entry[0], tables, self.widgets.node_stat.values.choices), 0)) nodes.add((graph_entry[1], node_label(graph_entry[1], tables, self.widgets.node_stat.values.choices), 0)) edges.add((edge_label(graph_entry[0], graph_entry[1], tables, self.widgets.edge_stat.values.choices), 0, graph_entry[0], graph_entry[1], True)) main_views += [self._get_widget('graph_%s' % network).view(nodes, edges)] main_view = stack_left(*main_views) return self.widgets.layout.view(main_view, control_panel_view)
def main_view(self, tables): dims = self.widgets.dims.get_choices() views = [] for table in tables: fig_widget = self._add_widget_if_needed('figure_%s' % table.name, Figure) ax = axes.new_axes(60 * len(dims), 500) axes.boxplot(ax, table, dims) views.append(fig_widget.view(ax.figure)) return stack_left(*views)
def view(self, data, place_in_chain, possible_inputs): def create_inputs_summary(): summary = [] for input in self.input_to_select: choices = self.input_to_select[input].values.choices choice_texts = [p[1] for p in possible_inputs if p[0] in choices] #summary.append('%s: %s' % (input, choice_text)) summary.append('|'.join(choice_texts)) ret = ', '.join(summary) if ret: return 'Inputs: %s ' % ret else: if self.input_to_select: return 'Inputs' else: return '' #input_summary = View(self, '%sOutputs: %s' % ( # create_inputs_summary(), # ', '.join(self.get_outputs()))) input_summary = View(self, create_inputs_summary()) input_content_views = [] for k,v in self.input_to_select.items(): input_content_views.append(v.view( k, self.widgets.input_apply, possible_inputs, multiple=True)) input_content_views.append(self.widgets.input_apply.view()) input_content = view.stack_lines(*input_content_views) try: sub_widget_view = self.widgets.sub_widget.view(**self.create_input_map(data)) except Exception as e: logging.exception('Exception in view') sub_widget_view = View(self, str(e)) global CHAINABLE_WIDGETS widget_control_view = stack_left( self.widgets.new_widget_select.view('', self.widgets.apply_new_widget, zip(*CHAINABLE_WIDGETS)[0], False), self.widgets.apply_new_widget.view('Add before'), self.widgets.delete_button.view('Delete')) widget_control_view.main_html = '<div style="position:absolute; top:0; right:0;">%s</div>' % widget_control_view.main_html sub_view = view.stack_lines( widget_control_view, self.widgets.input_panel.view(input_summary, input_content), view.vertical_seperator(), sub_widget_view) #sub_view = self.widgets.sub_widget.view(data) #title_view = view.left_right( # View(self, self.title(place_in_chain)), # self.widgets.delete_button.view('Delete')) title_view = View(self, self.title(place_in_chain)) return self.widgets.expander.view(title_view, sub_view)
def main_view(self, tables): if 'all' in self.widgets.tables_to_show.get_choices(): tables_to_show = tables else: tables_to_show = [ t for t in tables if t.name in self.widgets.tables_to_show.get_choices() ] if not tables_to_show: return # Assemble the figure to show figures_to_show = [] multi_timer = MultiTimer(len(tables_to_show)) for table_input in tables_to_show: figures_to_show.append( self._draw_figures(table_input, self.widgets.dim_x.get_choices(), self.widgets.dim_y.get_choices(), tables_to_show)) multi_timer.complete_task(table_input.name) # Draw the figures in a table lines = [] for key in figures_to_show[0].iterkeys(): line = [] for i in xrange(len(tables_to_show)): fig_widget = self._add_widget_if_needed( '%d_%s' % (i, key), Figure) fig, extra_view, fig_range = figures_to_show[i][key] # We give the view function a predefined id so that we can reference this viewed instance from # the areaselect widget in gating mode. widget_id = self._get_unique_id() if fig: fig_view = fig_widget.view(fig, id=widget_id) if self.enable_gating: area_select_widget = self._add_widget_if_needed( 'area_select_%s' % widget_id, AreaSelect) area_select_view = area_select_widget.view( widget_id, self.gate_min_x_id, self.gate_max_x_id, self.gate_min_y_id, self.gate_max_y_id, fig_range) fig_view = stack_lines(fig_view, area_select_view) else: fig_view = View(self, '') # On gating mode we want to add areaselect. line.append(stack_lines(fig_view, extra_view)) lines.append(line) if len(tables_to_show) == 1: return view.stack_left(*[l[0] for l in lines]) else: self._add_widget_if_needed('input_table', Table) return self.widgets.input_table.view( [table_input.name for table_input in tables_to_show], lines)
def view(self, tables): global NETWORKS self.widgets.network.guess_or_remember((tables, 'Network'), []) self.widgets.edge_stat.guess_or_remember((tables, 'Network'), []) self.widgets.node_stat.guess_or_remember((tables, 'Network'), []) control_panel_view = stack_lines( self.widgets.network.view('Network', self.widgets.apply, sorted(NETWORKS.keys())), self.widgets.edge_stat.view('Edge statistic to show', self.widgets.apply, sorted(EDGE_STATS.keys())), self.widgets.node_stat.view('Node statistic to show', self.widgets.apply, sorted(NODE_STATS.keys())), self.widgets.apply.view()) networks = [ n for n in self.widgets.network.values.choices if n in NETWORKS ] main_views = [] for network in networks: nodes = set() edges = set() for graph_entry in NETWORKS[network]: nodes.add( (graph_entry[0], node_label(graph_entry[0], tables, self.widgets.node_stat.values.choices), 0)) nodes.add( (graph_entry[1], node_label(graph_entry[1], tables, self.widgets.node_stat.values.choices), 0)) edges.add((edge_label(graph_entry[0], graph_entry[1], tables, self.widgets.edge_stat.values.choices), 0, graph_entry[0], graph_entry[1], True)) main_views += [ self._get_widget('graph_%s' % network).view(nodes, edges) ] main_view = stack_left(*main_views) return self.widgets.layout.view(main_view, control_panel_view)
def view(self, **tables): self.widgets.edge_stat.guess_or_remember((tables, 'Compare'), []) self.widgets.node_stat.guess_or_remember((tables, 'Compare'), []) NODE_STATS = ['values'] EDGE_STATS = [] control_panel_view = stack_lines( self.widgets.edge_stat.view('Edge statistics', self.widgets.apply, sorted(EDGE_STATS)), self.widgets.node_stat.view('Node statistics', self.widgets.apply, sorted(NODE_STATS)), self.widgets.apply.view()) data_tables = [t for t in tables.values() if t] networks = [ n for n in self.widgets.network.values.choices if n in NETWORKS ] main_views = [] for network in networks: nodes = set() edges = set() for graph_entry in NETWORKS[network]: nodes.add( (graph_entry[0], node_label(graph_entry[0], data_tables, self.widgets.node_stat.values.choices), 0)) nodes.add( (graph_entry[1], node_label(graph_entry[1], data_tables, self.widgets.node_stat.values.choices), 0)) edges.add( (edge_label(graph_entry[0], graph_entry[1], data_tables, self.widgets.edge_stat.values.choices), 0, graph_entry[0], graph_entry[1], True)) main_views += [ self._get_widget('graph_%s' % network).view(nodes, edges) ] main_view = stack_left(*main_views) return self.widgets.layout.view(main_view, control_panel_view)
def main_view(self, tables): if 'all' in self.widgets.tables_to_show.get_choices(): tables_to_show = tables else: tables_to_show = [t for t in tables if t.name in self.widgets.tables_to_show.get_choices()] if not tables_to_show: return # Assemble the figure to show figures_to_show = [] multi_timer = MultiTimer(len(tables_to_show)) for table_input in tables_to_show: figures_to_show.append(self._draw_figures(table_input, self.widgets.dim_x.get_choices(), self.widgets.dim_y.get_choices(), tables_to_show)) multi_timer.complete_task(table_input.name) # Draw the figures in a table lines = [] for key in figures_to_show[0].iterkeys(): line = [] for i in xrange(len(tables_to_show)): fig_widget = self._add_widget_if_needed('%d_%s' % (i, key), Figure) fig, extra_view, fig_range = figures_to_show[i][key] # We give the view function a predefined id so that we can reference this viewed instance from # the areaselect widget in gating mode. widget_id = self._get_unique_id() if fig: fig_view = fig_widget.view(fig, id=widget_id) if self.enable_gating: area_select_widget = self._add_widget_if_needed('area_select_%s' % widget_id, AreaSelect) area_select_view = area_select_widget.view( widget_id, self.gate_min_x_id, self.gate_max_x_id, self.gate_min_y_id, self.gate_max_y_id, fig_range) fig_view = stack_lines(fig_view, area_select_view) else: fig_view = View(self, '') # On gating mode we want to add areaselect. line.append(stack_lines(fig_view, extra_view)) lines.append(line) if len(tables_to_show) == 1: return view.stack_left(*[l[0] for l in lines]) else: self._add_widget_if_needed('input_table', Table) return self.widgets.input_table.view([table_input.name for table_input in tables_to_show], lines)
def view(self): experiments = settings.EXPERIMENTS.keys() if not self.experiment: return stack_lines( self.widgets.experiment_select.view( 'Please Select an experiment', self.widgets.apply, experiments, False), self.widgets.apply.view()) if not self.experiment in self.experiment_to_widgets: index = self._get_index() widgets = [] if type(settings.EXPERIMENTS[self.experiment]) == tuple: editable_tags = settings.EXPERIMENTS[self.experiment][1] else: editable_tags = index.all_tags() for tag in editable_tags: new_widget = self._add_widget('%s_%s' % (self.experiment, tag), Select) new_widget.tag = tag new_widget.vals = index.all_values_for_tag(tag) widgets.append(new_widget) self.experiment_to_widgets[self.experiment] = widgets views = [ w.view(w.tag, self.widgets.apply, w.vals) for w in self.experiment_to_widgets[self.experiment] ] stacked_views = stack_left(*views) expanded = stack_lines( self.widgets.experiment_select.view('Experiment', self.widgets.apply, experiments, False), stacked_views, View(None, '<p style="clear: both"></p>'), self.widgets.apply.view()) #return expanded return self.widgets.expander.view('', [self.summary], [expanded])
def view(self, table, dims, remove_negative_values=True, cluster=False, size=200): if table.num_cells < 10: return View(self, 'Not enough cells') lines = [] timer = MultiTimer(len(dims)) for dim in dims: if remove_negative_values: positive_table = table.remove_bad_cells(dim) else: positive_table = table if positive_table.num_cells < 10: # TODO: add print error here continue line = [] # 1 - Dimension line.append(dim) # 2 - Kde1d axes_main = new_axes(size,size) try: axes.kde1d(axes_main, positive_table, dim) except: logging.exception('kde1d exception') print positive_table.num_cells kde_view = self.widgets.kde1d_fig.view(axes_main.figure) stat_table = positive_table.get_stats(dim) stats_view = self.widgets.stat_table.view(stat_table.dims, stat_table.data, True) line.append(view.stack_left(kde_view, stats_view)) if cluster: # 4 - GMM axes_clusters = new_axes(size,size) ((cluster1, cluster2), llh) = positive_table.emgm((dim,), 2, auto_centers=True) if cluster1.num_cells < 10 or cluster2.num_cells < 10: line.append('Not enough cells in one of the clusters') else: try: axes.kde1d(axes_clusters, cluster1, dim, norm = cluster1.num_cells / positive_table.num_cells) except: logging.exception('kde1d failed') try: axes.kde1d(axes_clusters, cluster2, dim, norm = cluster2.num_cells / positive_table.num_cells) except: logging.exception('kde1d failed') combined_stats = combine_tables([cluster1.get_stats(dim), cluster2.get_stats(dim)]) line.append( view.stack_left( self.widgets.kde1d_fig.view(axes_clusters.figure), self.widgets.stat_table.view(combined_stats.dims, combined_stats.data, True))) line.append(llh) if False: #5 - KMEANS axes_clusters = new_axes(size,size) cluster1, cluster2 = positive_table.kmeans((dim,), 2) if cluster1.num_cells > 100: axes.kde1d(axes_clusters, cluster1, dim, norm = cluster1.num_cells / positive_table.num_cells) if cluster2.num_cells > 100: axes.kde1d(axes_clusters, cluster2, dim, norm = cluster2.num_cells / positive_table.num_cells) line.append(self.widgets.kde1d_fig.view(axes_clusters.figure)) lines.append(line) timer.complete_task(dim) if cluster: titles = ['Dimension', 'Histogram', 'Gaussian Mixture','GM Log likelihood 2 clusters'] else: titles = ['Dimension', 'Histogram'] return self.widgets.table.view( titles, lines, None, [('Dimension', 'asc')])
def view(self, data, place_in_chain, possible_inputs): def create_inputs_summary(): summary = [] for input in self.input_to_select: choices = self.input_to_select[input].values.choices choice_texts = [ p[1] for p in possible_inputs if p[0] in choices ] #summary.append('%s: %s' % (input, choice_text)) summary.append('|'.join(choice_texts)) ret = ', '.join(summary) if ret: return 'Inputs: %s ' % ret else: if self.input_to_select: return 'Inputs' else: return '' #input_summary = View(self, '%sOutputs: %s' % ( # create_inputs_summary(), # ', '.join(self.get_outputs()))) input_summary = View(self, create_inputs_summary()) input_content_views = [] for k, v in self.input_to_select.items(): input_content_views.append( v.view(k, self.widgets.input_apply, possible_inputs, multiple=True)) input_content_views.append(self.widgets.input_apply.view()) input_content = view.stack_lines(*input_content_views) try: sub_widget_view = self.widgets.sub_widget.view( **self.create_input_map(data)) except Exception as e: logging.exception('Exception in view') sub_widget_view = View(self, str(e)) global CHAINABLE_WIDGETS widget_control_view = stack_left( self.widgets.new_widget_select.view('', self.widgets.apply_new_widget, zip(*CHAINABLE_WIDGETS)[0], False), self.widgets.apply_new_widget.view('Add before'), self.widgets.delete_button.view('Delete')) widget_control_view.main_html = '<div style="position:absolute; top:0; right:0;">%s</div>' % widget_control_view.main_html sub_view = view.stack_lines( widget_control_view, self.widgets.input_panel.view(input_summary, input_content), view.vertical_seperator(), sub_widget_view) #sub_view = self.widgets.sub_widget.view(data) #title_view = view.left_right( # View(self, self.title(place_in_chain)), # self.widgets.delete_button.view('Delete')) title_view = View(self, self.title(place_in_chain)) return self.widgets.expander.view(title_view, sub_view)
def view(self, table, dims, remove_negative_values=True, cluster=False, size=200): if table.num_cells < 10: return View(self, 'Not enough cells') lines = [] timer = MultiTimer(len(dims)) for dim in dims: if remove_negative_values: positive_table = table.remove_bad_cells(dim) else: positive_table = table if positive_table.num_cells < 10: # TODO: add print error here continue line = [] # 1 - Dimension line.append(dim) # 2 - Kde1d axes_main = new_axes(size, size) try: axes.kde1d(axes_main, positive_table, dim) except: logging.exception('kde1d exception') print positive_table.num_cells kde_view = self.widgets.kde1d_fig.view(axes_main.figure) stat_table = positive_table.get_stats(dim) stats_view = self.widgets.stat_table.view(stat_table.dims, stat_table.data, True) line.append(view.stack_left(kde_view, stats_view)) if cluster: # 4 - GMM axes_clusters = new_axes(size, size) ((cluster1, cluster2), llh) = positive_table.emgm( (dim, ), 2, auto_centers=True) if cluster1.num_cells < 10 or cluster2.num_cells < 10: line.append('Not enough cells in one of the clusters') else: try: axes.kde1d(axes_clusters, cluster1, dim, norm=cluster1.num_cells / positive_table.num_cells) except: logging.exception('kde1d failed') try: axes.kde1d(axes_clusters, cluster2, dim, norm=cluster2.num_cells / positive_table.num_cells) except: logging.exception('kde1d failed') combined_stats = combine_tables( [cluster1.get_stats(dim), cluster2.get_stats(dim)]) line.append( view.stack_left( self.widgets.kde1d_fig.view(axes_clusters.figure), self.widgets.stat_table.view( combined_stats.dims, combined_stats.data, True))) line.append(llh) if False: #5 - KMEANS axes_clusters = new_axes(size, size) cluster1, cluster2 = positive_table.kmeans((dim, ), 2) if cluster1.num_cells > 100: axes.kde1d(axes_clusters, cluster1, dim, norm=cluster1.num_cells / positive_table.num_cells) if cluster2.num_cells > 100: axes.kde1d(axes_clusters, cluster2, dim, norm=cluster2.num_cells / positive_table.num_cells) line.append(self.widgets.kde1d_fig.view(axes_clusters.figure)) lines.append(line) timer.complete_task(dim) if cluster: titles = [ 'Dimension', 'Histogram', 'Gaussian Mixture', 'GM Log likelihood 2 clusters' ] else: titles = ['Dimension', 'Histogram'] return self.widgets.table.view(titles, lines, None, [('Dimension', 'asc')])
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)