def add_peak_selector(self,peak_list,dataset,callback): self.remove_line_tool() self.zoom_tool.drag_button = None self.peak_selector_tool=PeakSelectorTool(peak_list,dataset,callback,self.plot) height= self.plot.container.height self.peak_selector_tool_tip=ToolTip(component=self.plot.container, bgcolor='yellow',lines=["left-click to select peaks, press ENTER to fit curve to each"],padding=10, position=[0,height]) self.plot.overlays.append(self.peak_selector_tool) self.plot.overlays.append(self.peak_selector_tool_tip) self.peak_selector_tool.request_redraw()
class RawDataPlot(HasTraits): plot = Instance(Component) line_tool=None background_fit=None selected_ranges=[] current_selector=None peak_selector_tool=None def __init__(self): self.plots = {} self._setup_plot() def plot_datasets(self, datasets, scale='linear', reset_view=True): if self.plots: self.plot.delplot(*self.plot.plots.keys()) self.plots = {} active = filter(lambda d: d.metadata['ui'].active, datasets) hilite = filter(lambda d: d.metadata['ui'].markers, active) if len(active)==0: return None for dataset in active: ui = dataset.metadata['ui'] data = dataset.data name = ui.name or dataset.name x, y = np.transpose(data[:, [0,1]]) self.plot_data.set_data(name + '_x', x) self.plot_data.set_data(name + '_y', rescale(y, method=scale)) color = ui.color if color is None: color = 'auto' plot = self.plot.plot((name + '_x', name + '_y'), name=name, type='line', color=color, line_width=ui.line_width) if color == 'auto': ui.color = tuple( (np.array(plot[0].color_) * 255).astype('uint8').tolist()) self.plots[name] = plot for dataset in hilite: ui = dataset.metadata['ui'] data = dataset.data name = ui.name or dataset.name # Overlay a scatter plot on the original line plot to highlight # data points as circles. plot = self.plot.plot((name + '_x', name + '_y'), name=name + '_selection', type='scatter', color=ui.color, outline_color=ui.color, marker_size=ui.marker_size, line_width=ui.line_width) self.plots[name] = plot if len(datasets) > 0: self.plot0renderer = plot[0] self.range_selection_tool = RangeSelection(self.plot0renderer, left_button_selects=True) self.range_selection_overlay = RangeSelectionOverlay(component=self.plot0renderer) if reset_view: self.reset_view() # Since highlighted datasets are plotted twice, both plots show up in # the legend. This fixes that. self.plot.legend.plots = self.plots self.show_legend('Overlay') self._set_scale(scale) def reset_view(self): self.plot.index_range.reset() self.plot.value_range.reset() #self.zoom_tool.clear_undo_history() def _set_scale(self, scale): self.plot.y_axis.title = 'Intensity (%s)' % get_value_scale_label(scale) def show_legend(self, legend='Overlay'): if legend=='Window': self.legend = self.plot.legend self.plot.legend=None self.legend_window = LegendWindow(self.legend) # self.legend_window._plot() self.legend_window.edit_traits() #self.plot.legend.overlay(newplot) #self.plot.legend.visible = True # create new window with legend in it elif legend=='Off': if hasattr(self,'legend'): # legend in sepate window exists self.legend.set(component=self.plot) self.plot.legend = self.legend self.plot.legend.visible = False else: if hasattr(self,'legend'): # legend in sepate window exists self.legend.set(component=self.plot) self.plot.legend = self.legend self.plot.legend.visible = True def show_grids(self, visible=True): self.plot.x_grid.visible = visible self.plot.y_grid.visible = visible def show_crosslines(self, visible=True): for crossline in self.crosslines: crossline.visible = visible if visible: self.pointer_tool.inner_pointer = 'blank' else: self.pointer_tool.inner_pointer = 'cross' def get_plot(self): return self.plot def start_range_select(self): self.plot0renderer.tools.append(self.range_selection_tool) self.plot0renderer.overlays.append(self.range_selection_overlay) # disable zoom tool and change selection cursor to a vertical line self.zoom_tool.drag_button = None self.crosslines_x_state = self.crosslines[0].visible self.crosslines_y_state = self.crosslines[1].visible self.crosslines[0].visible = True self.crosslines[1].visible = False self.current_selector=self.range_selection_tool def end_range_select(self): self.plot0renderer.tools.remove(self.range_selection_tool) self.plot0renderer.overlays.remove(self.range_selection_overlay) # reenable zoom tool and change selection cursor back to crossed lines self.zoom_tool.drag_button = 'left' self.crosslines[0].visible = self.crosslines_x_state self.crosslines[1].visible = self.crosslines_y_state return self.range_selection_tool.selection def add_new_range_select(self): if (len(self.selected_ranges)==0): self.start_range_select() new_range_selector=self.range_selection_tool self.selected_ranges.append(self.range_selection_tool) else: new_range_selector = RangeSelection(self.plot0renderer, left_button_selects=True) self.plot0renderer.tools.append(self.range_selection_tool) self.selected_ranges.append(new_range_selector) return new_range_selector def remove_tooltips(self,tool): if tool=='peak_selector': if self.peak_selector_tool_tip: self.plot.overlays.remove(self.peak_selector_tool_tip) self.peak_selector_tool_tip=None if tool=='line_drawer_tool': if self.line_drawer_tool_tip: self.plot.overlays.remove(self.line_drawer_tool_tip) self.line_drawer_tool_tip=None def add_line_drawer(self,datasets1,fitter,callback,background_manual): self.zoom_tool.drag_button = None self.line_tool=MyLineDrawer(self.plot,datasets=datasets1,curve_fitter=fitter,plot_callback=callback,background_manual=background_manual) self.line_drawer_tool_tip=ToolTip(component=self.plot.container,bgcolor='yellow',lines=["left-click to define points and press ENTER to fit a spline to the points"], padding=10, position=[0,self.plot.container.height]) self.plot.overlays.append(self.line_tool) self.plot.overlays.append(self.line_drawer_tool_tip) def remove_line_tool(self): if self.line_tool: if self.line_tool in self.plot.overlays: self.plot.overlays.remove(self.line_tool) self.remove_tooltips('line_drawer_tool') self.line_tool=None self.zoom_tool.drag_button='left' def add_peak_selector(self,peak_list,dataset,callback): self.remove_line_tool() self.zoom_tool.drag_button = None self.peak_selector_tool=PeakSelectorTool(peak_list,dataset,callback,self.plot) height= self.plot.container.height self.peak_selector_tool_tip=ToolTip(component=self.plot.container, bgcolor='yellow',lines=["left-click to select peaks, press ENTER to fit curve to each"],padding=10, position=[0,height]) self.plot.overlays.append(self.peak_selector_tool) self.plot.overlays.append(self.peak_selector_tool_tip) self.peak_selector_tool.request_redraw() def remove_peak_selector(self): if self.peak_selector_tool: self.plot.overlays.remove(self.peak_selector_tool) self.remove_tooltips('peak_selector') self.peak_selector_tool=None self.zoom_tool.drag_button='left' def reset_tools(self): self.remove_line_tool() self.remove_peak_selector() # need to also make sure that the peak labels are removed properly def update_peak_labels(self,peak_labels,peak_list,peak_profile): for label in peak_labels: self.plot.overlays.remove(label) # for dsp in editor.dataset_peaks: peak_labels=[] new_peak_list=[] for peak in peak_list: new_peak_list.append(peak) pos_index=np.where(peak_profile.data[:,0]==peak.position) label_intensity=peak_profile.data[pos_index[0],1] label=DataLabel(component=self.plot, data_point=[peak.position,label_intensity],\ label_position="right", padding=20, arrow_visible=True, label_format='(%(x)f') self.plot.overlays.append(label) peak_labels.append(label) return peak_labels def remove_peak_labels(self,peak_labels): for label in peak_labels: if label in set(self.plot.overlays): self.plot.overlays.remove(label) def _setup_plot(self): self.plot_data = ArrayPlotData() self.plot = MyPlotClass(self.plot_data, padding_left=120, fill_padding=True, bgcolor="white", use_backbuffer=True) self._setup_plot_tools(self.plot) # Recreate the legend so it sits on top of the other tools. self.plot.legend = Legend(component=self.plot, padding=10, error_icon='blank', visible=False, scrollable=True, plots=self.plots,clip_to_component=True) self.plot.legend.tools.append(LegendTool(self.plot.legend, drag_button="right")) self.plot.x_axis = MyPlotAxis(component=self.plot, orientation='bottom') self.plot.y_axis = MyPlotAxis(component=self.plot, orientation='left') self.plot.x_axis.title = ur'Angle (2\u0398)' tick_font = settings.tick_font self.plot.x_axis.title_font = settings.axis_title_font self.plot.y_axis.title_font = settings.axis_title_font self.plot.x_axis.tick_label_font = tick_font self.plot.y_axis.tick_label_font = tick_font #self.plot.x_axis.tick_out = 0 #self.plot.y_axis.tick_out = 0 self._set_scale('linear') # Add the traits inspector tool to the container self.plot.tools.append(TraitsTool(self.plot)) def _setup_plot_tools(self, plot): """Sets up the background, and several tools on a plot""" plot.bgcolor = "white" # The ZoomTool tool is stateful and allows drawing a zoom # box to select a zoom region. self.zoom_tool = ClickUndoZoomTool(plot, #self.zoom_tool = ZoomTool(plot, x_min_zoom_factor=-inf, y_min_zoom_factor=-inf, tool_mode="box", always_on=True, drag_button=settings.zoom_button, # undo_button=settings.undo_button, zoom_to_mouse=True) # The PanTool allows panning around the plot self.pan_tool = KeyboardPanTool(plot, drag_button=settings.pan_button, history_tool=self.zoom_tool) plot.tools.append(self.pan_tool) plot.overlays.append(self.zoom_tool) x_crossline = LineInspector(component=plot, axis='index_x', inspect_mode="indexed", is_listener=False, draw_mode='overlay', color="grey") y_crossline = LineInspector(component=plot, axis='index_y', inspect_mode="indexed", color="grey", draw_mode='overlay', is_listener=False) plot.overlays.append(x_crossline) plot.overlays.append(y_crossline) self.crosslines = (x_crossline, y_crossline) # The RangeSelectionTool tool is stateful and allows selection of a candidate # range for dataseries alignment. # plot.overlays.append(RangeSelectionOverlay(component=plot)) tool = SimpleInspectorTool(plot) plot.tools.append(tool) overlay = SimpleInspectorOverlay(component=plot, inspector=tool, align="lr") def formatter(**kw): return '(%.2f, %.2f)' % (kw['x'], kw['y']) overlay.field_formatters = [[formatter]] overlay.alternate_position = (-25, -25) plot.overlays.append(overlay) self.pointer_tool = PointerControlTool(component=plot, pointer='arrow') plot.tools.append(self.pointer_tool)