class ListTraitTest(HasStrictTraits): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- people = List(Person) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View(VSplit(Item('people', id='table', editor=table_editor), Item('people@', id='list', editor=ListEditor(style='custom', rows=5)), Item('people@', id='notebook', editor=ListEditor(use_notebook=True, deletable=True, export='DockShellWindow', page_name='.name')), id='splitter', show_labels=False), title='List Trait Editor Test', id='enthought.traits.ui.tests.list_traits_ui_test', dock='horizontal', width=.4, height=.6, resizable=True, buttons=NoButtons, kind='live')
class ShapeSelector(HasTraits): select = Enum(*[cls.__name__ for cls in Shape.__subclasses__()]) shape = Instance(Shape) view = View(VGroup( Item("select", show_label=False), VSplit(Item("shape", style="custom", editor=InstanceEditor(view="view")), Item("shape", style="custom", editor=InstanceEditor(view="view_info")), show_labels=False)), width=350, height=300, resizable=True) def __init__(self, **traits): super(ShapeSelector, self).__init__(**traits) self._select_changed() def _select_changed(self): klass = [ c for c in Shape.__subclasses__() if c.__name__ == self.select ][0] self.shape = klass()
def default_traits_view(self): view = View( HSplit( VSplit( Item("object_class", editor=self.tree_editor, show_label=False, visible_when="object.show_tree"), Group( Item("search", label="搜索"), Item("search_result_str", show_label=False, editor=ListStrEditor(editable=False, selected_index="search_result_index")), label="Search"), ), Item("current_document", style="custom", show_label=False, editor=CodeEditor(lexer="null", search="top", line = "current_line", mark_lines="mark_lines", mark_color=0xff7777)), id = "tvtkdoc.hsplit" ), width = 700, height = 500, resizable = True, title = "TVTK文档浏览器", id = "tvtkdoc", handler = TVTKDocumentHandler(), ) return view
def default_traits_view(self): view = View(VSplit( HGroup( Group( spring, Item('delimiter', label='Column delimiter character'), Item('comments', label='Comment character'), Item('skiprows', label='Number of lines to skip at the ' 'beginning of the file'), spring, Item('handler.update_preview', show_label=False), ), Group( Item( 'columns', show_label=False, style='readonly', editor=ListEditor(style='custom'), springy=True, ), label="Column names", show_border=True, ), ), Group(Group( Item( 'data', show_label=False, editor=self.tabular_editor, ), label="Preview table", ), Group( Item('handler.file_content', style='readonly', show_label=False, springy=True), label="%s" % self.model.filename, ), layout='tab'), ), buttons=['OK', 'Cancel', 'Help'], id='csv_load_editor', resizable=True, width=640, height=580, title='CSV import - [%s]' % self.model.filename) return view
class Model(HasTraits): a = Code("print 'hello'") b = Button("click me") traits_view = View(HSplit( VGroup( Tabbed( Item('a'), Item('a'), Item('a')), Item('b')), VSplit( VGroup('b','b','b'), HGroup('a', show_border=True, label="traits is great")), dock="horizontal" ), resizable=True, id="my.test.program.id")
class PythonBrowser ( HasPrivateTraits ): dir = Directory files = List( FileInfo ) file_info = Instance( FileInfo ) code = Code view = View( HSplit( Item( 'dir', style = 'custom' ), VSplit( Item( 'files', editor = tabular_editor ), Item( 'code', style = 'readonly' ), show_labels = False ), show_labels = False ), resizable = True, width = 0.75, height = 0.75 ) #-- Event Handlers --------------------------------------------------------- def _dir_changed ( self, dir ): self.files = [ FileInfo( file_name = join( dir, name ) ) for name in listdir( dir ) if ((splitext( name )[1] == '.py') and isfile( join( dir, name ) )) ] def _file_info_changed ( self, file_info ): fh = None try: fh = open( file_info.file_name, 'rb' ) self.code = fh.read() except: pass if fh is not None: fh.close()
class CSModelView(ModelView): model = Instance(ClampSetup) def _model_default(self): return ClampSetup() figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') figure.add_axes([0.08, 0.13, 0.85, 0.74]) return figure data_changed = Event @on_trait_change('model.+modified') def refresh(self): figure = self.figure axes = figure.gca() axes.clear() cs = self.model xu, u, xe, e = cs.get_values() axes.set_xlabel('position on yarn', weight='semibold') axes.set_axis_bgcolor(color='white') axes.ticklabel_format(scilimits=(-3., 4.)) axes.grid(color='gray', linestyle='--', linewidth=0.5, alpha=0.7) if cs.switch == 'strains': axes.plot(xe, e, lw=2, color='blue') axes.set_ylabel('strains [-]', weight='semibold') axes.plot(array([cs.l1, cs.l1]), array([0, max(e)]), lw=2, color='red', linestyle='dashed') axes.plot(array([cs.l1 + cs.L, cs.l1 + cs.L]), array([0, max(e)]), lw=2, color='red', linestyle='dashed') axes.text(cs.l1 + cs.L / 2, max(e) * 0.95, 'clamp', size='large', ha='center') axes.text(cs.l1 + cs.L + cs.lt / 2, max(e) * 0.95, 'tested length', size='large', ha='center') elif cs.switch == 'displacement': axes.plot(xu, u, lw=2, color='blue') axes.set_ylabel('displacement [m]', weight='semibold') axes.plot(array([cs.l1, cs.l1]), array([0, max(u)]), lw=2, color='red', linestyle='dashed') axes.plot(array([cs.l1 + cs.L, cs.l1 + cs.L]), array([0, max(u)]), lw=2, color='red', linestyle='dashed') axes.text(cs.l1 + cs.L / 2, max(u) * 0.95, 'clamp', size='large', ha='center') axes.text(cs.l1 + cs.L + cs.lt / 2, max(u) * 0.95, 'tested length', size='large', ha='center') else: print 'NOT YET IMPLEMENTED' # axes.plot(xslip, yslip, lw = 2, color = 'blue') # axes.set_ylabel('slip in clamp [m]', weight = 'semibold') # axes.set_xlabel('position in clamp [mm]', weight = 'semibold') self.data_changed = True traits_view = View(HSplit( VGroup( Item('model@', show_label=False, resizable=True), label='Material parameters', id='cs.viewmodel.model', dock='tab', ), VSplit( VGroup( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), label='yarn displacement', id='cs.viewmodel.plot_window', dock='tab', ), id='cs.viewmodel.right', ), id='cs.viewmodel.splitter', ), title='tested yarn', id='cs.viewmodel', dock='tab', resizable=True, buttons=[OKButton], height=0.8, width=0.8)
class tcWindow(HasTraits): project = tcProject plot = tcPlot def __init__(self, project): self.project = project self.plot = create_timechart_container(project) self.plot_range_tools = self.plot.range_tools self.plot_range_tools.on_trait_change(self._selection_time_changed, "time") self.trait_view().title = self.get_title() def get_title(self): if self.project.filename == "dummy": return "PyTimechart: Please Open a File" return "PyTimechart:" + self.project.filename # Create an action that exits the application. status = Str("Welcome to PyTimechart") traits_view = View( HSplit( VSplit( Item('project', show_label=False, editor=InstanceEditor(view='process_view'), style='custom', width=150), # Item('plot_range_tools', show_label = False, editor=InstanceEditor(view = 'selection_view'), style='custom',width=150,height=100) ), Item('plot', show_label=False, editor=ComponentEditor()), ), toolbar=ToolBar(*_create_toolbar_actions(), image_size=(24, 24), show_tool_names=False), menubar=MenuBar(*_create_menubar_actions()), statusbar=[ StatusItem(name='status'), ], resizable=True, width=1280, height=1024, handler=tcActionHandler()) def _on_open_trace_file(self): if open_file(None) and self.project.filename == "dummy": self._ui.dispose() def _on_view_properties(self): self.plot.options.edit_traits() def _on_exit(self, n=None): self.close() sys.exit(0) def close(self, n=None): pass def _on_about(self): aboutBox().edit_traits() def _on_doc(self): browse_doc() def _selection_time_changed(self): self.status = "selection time:%s" % (self.plot_range_tools.time)
class MainWindow(HasTraits): parameter_file_collections = Instance(ParameterFileCollectionList) parameter_files = Instance(ParameterFileCollection) plot_frame_tabs = List(Instance(DataObject)) open_parameterfile = Button shell = PythonValue def _shell_default(self): return globals() notebook_editor = ListEditor(editor=InstanceEditor(editable=True), use_notebook=True) traits_view = View( VSplit( HSplit( VGroup( Item( 'parameter_file_collections', width=120.0, height=500.0, show_label=False, editor=TreeEditor( editable=False, nodes=[ TreeNode( node_for=[ParameterFileCollectionList], children='parameter_file_collections', label="=Data Collections"), TreeNode(node_for=[ParameterFileCollection], children='parameter_files', label="name", view=View()), TreeNode(node_for=[ParameterFile], children='data_objects', label="name", menu=Menu( Action(name='Slice', action='object.do_slice'), Action(name='Project', action='object.do_proj'), Action(name='VTK', action='object.do_vtk')), view=View()), TreeNode(node_for=[DataObject], children='', label="name"), ], show_icons=False), ), Item('open_parameterfile', show_label=False)), Item('plot_frame_tabs', style='custom', editor=notebook_editor, show_label=False, height=500.0, width=500.0), ), HGroup( #Item('shell', editor=ShellEditor(share=True), #show_label=False, height=120.0), ), ), resizable=True, width=800.0, height=660.0, title="reason v2 [prototype]") def _open_parameterfile_fired(self): print "OPENING" def _parameter_file_collections_default(self): return ParameterFileCollectionList()
class OverlayMap(HasTraits): """ Use mayavi to plot three image cut planes through an fMRI volume and stat-map overlay. """ # Main scene scene = Instance(MlabSceneModel, ()) # the image planes and lookup tables overlays = List(Instance(ImagePlaneWidget)) underlays = List(Instance(ImagePlaneWidget)) over_lut = Instance(HasTraits) under_lut = Instance(HasTraits) # lower range of the overlay lookup table _over_low_min = Float(0.0) _over_low_max = Float(0.1) over_low = Range(low='_over_low_min', high='_over_low_max', value=0.0, mode='slider') # upper range of the overlay lookup table _over_hi_min = Float(0.0) _over_hi_max = Float(0.1) over_hi = Range(low='_over_hi_min', high='_over_hi_max', value=0.01, mode='slider') # Whether to see x,y,z planes x_visible = Bool(True) y_visible = Bool(True) z_visible = Bool(True) # Which colormap to use colormap = Enum("hot", "jet", "autumn") def __init__(self, under_image, over_image): """ Provide the underlay and overlay NiftiImages. Can also provide filename strings. Example: stat = OverlayMap('anat.nii.gz','stat.nii.gz') """ # we've got traits HasTraits.__init__(self) # load in the image if isinstance(under_image, NiftiImage): # use it self.__under_image = under_image elif isinstance(under_image, str): # load from file self.__under_image = NiftiImage(under_image) else: raise ValueError("under_image must be a NiftiImage or a file.") # TODO: set the extent and spacing of the under image # set the over data if isinstance(over_image, str): # load from file over_image = NiftiImage(over_image) if isinstance(over_image, NiftiImage): # TODO: make sure it matches the dims of under image # TODO: set the extent # save just the dat self.__over_image = over_image.data.T elif isinstance(over_image, np.ndarray): # just set it # assumes it matches the dims and extent of the under image self.__over_image = over_image else: raise ValueError("over_image must be a NiftiImage, ndarray, or file.") self.__over_image = np.ma.masked_invalid(self.__over_image) self.configure_traits() pass def _plane_callback1(self, widget, event): self._update_planes(0) def _plane_callback2(self, widget, event): self._update_planes(1) def _plane_callback3(self, widget, event): self._update_planes(2) def _update_planes(self,num): # set the underlay positions. # TODO: it may make more sense to do this in the callback for # each individual plane when it is called instead of all at # once #for i in range(len(self.overlays)): #if widget == self.overlays[i]: # print "widget is overlay", i #elif widget == self.underlays[i]: # print "widget is underlay", i #else: # print "widget", widget # from what I can tell, all these are necessary self.underlays[num].ipw.update_traits() self.overlays[num].ipw.origin = self.underlays[num].ipw.origin self.overlays[num].ipw.point1 = self.underlays[num].ipw.point1 self.overlays[num].ipw.point2 = self.underlays[num].ipw.point2 self.overlays[num].ipw.update_traits() self.overlays[num].ipw.update_placement() #self.overlays[num].scene.render() @on_trait_change('scene.activated') def _create_plot(self): # shorten things a bit mlab = self.scene.mlab # generate the scalar_fields over = mlab.pipeline.scalar_field(np.ma.masked_invalid(self.__over_image).filled(0)) #over_thresh = mlab.pipeline.threshold(over,low=self.__over_image.mean()) under = mlab.pipeline.scalar_field(np.ma.masked_invalid(self.__under_image.data.T).filled(0)) # create the planes for the x,y,z axes self.underlays = [] self.overlays = [] for orient in ['x_axes','y_axes','z_axes']: # first the underlay # TODO: fix the slice_index, which is a hack under = mlab.pipeline.image_plane_widget(under,colormap='gray', slice_index=92, plane_opacity=0, plane_orientation=orient) # set up the lookup table under.ipw.user_controlled_lookup_table = True if self.under_lut is None: # set it self.under_lut = under.module_manager.scalar_lut_manager.lut else: # use it under.module_manager.scalar_lut_manager.lut.table = self.under_lut.table # add the interaction event if orient == "x_axes": under.ipw.add_observer("InteractionEvent", self._plane_callback1) elif orient == "y_axes": under.ipw.add_observer("InteractionEvent", self._plane_callback2) else: under.ipw.add_observer("InteractionEvent", self._plane_callback3) # add it to the list self.underlays.append(under) # set up the overlay # TODO: fix the slice_index, which is a hack over = mlab.pipeline.image_plane_widget(over, colormap=self.colormap, slice_index=92, plane_opacity=0, plane_orientation=orient) # set the lookup table over.ipw.user_controlled_lookup_table = True if self.over_lut is None: # is first one, so set it with alpha at bottom lut = over.module_manager.scalar_lut_manager.lut.table.to_array() lut[:40, -1] = np.linspace(0,255,40) over.module_manager.scalar_lut_manager.lut.table = lut self.over_lut = over.module_manager.scalar_lut_manager.lut else: # use it over.module_manager.scalar_lut_manager.lut.table = self.over_lut.table # turn off the interaction over.ipw.interaction = False # append self.overlays.append(over) # set the overlay upper bounds range over_min = np.ma.masked_invalid(self.__over_image).min() over_max = np.ma.masked_invalid(self.__over_image).max() over_mean = np.ma.masked_invalid(self.__over_image).mean() print "mmm:", over_min, over_max, over_mean self._over_hi_min = float(over_min) #self.__over_image.min() self._over_hi_max = float(over_max) #self.__over_image.max() self.over_hi = over_max #self.__over_image.max() # set the overlay lower bounds range self._over_low_min = float(over_min) #self.__over_image.min() self._over_low_max = float(over_max) #self.__over_image.max() self.over_low = over_mean #self.__over_image.mean() #@on_trait_change('over_hi') def _over_hi_changed(self): if self.over_hi < self.over_low: # set low to be hi self.over_low = self.over_hi else: # update the range self._update_overlay_range() #@on_trait_change('over_low') def _over_low_changed(self): if self.over_low > self.over_hi: # set hi to be low self.over_hi = self.over_low else: # update the range self._update_overlay_range() def _update_overlay_range(self): # XXX: Do I need to copy here? new_range = self.overlays[0].module_manager.scalar_lut_manager.data_range.copy() new_range[0] = self.over_low new_range[1] = self.over_hi for i in range(len(self.overlays)): self.overlays[i].module_manager.scalar_lut_manager.data_range = new_range def _x_visible_changed(self): # toggle the proper plane on or off self._update_plane_visible(0,self.x_visible) def _y_visible_changed(self): # toggle the proper plane on or off self._update_plane_visible(1,self.y_visible) def _z_visible_changed(self): # toggle the proper plane on or off self._update_plane_visible(2,self.z_visible) def _update_plane_visible(self, plane_id, bool_val): self.underlays[plane_id].visible = bool_val self.overlays[plane_id].visible = bool_val def _colormap_changed(self): print self.colormap for o in self.overlays: #TODO: Change colormap, don't know how exactly #print o.module_manager.scalar_lut_manager.lut pass # define the view view = View( VSplit( Group(Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=500, width=500, show_label=False)), Group( Group(Item('over_low', label="Lower Thresh"), Item('over_hi', label="Upper Thresh"), label="Overlay Properties", show_border=True), ), Group( HGroup(Item('x_visible'), Item('y_visible'), Item('z_visible'), Item('colormap'), label="Plane visibility + colormap", show_border=True), ), ), resizable=True, title='Overlay Viewer')
class Images(HasTraits): """Main class for image point selections """ filenames = Instance(Filenames, ()) analysis = Instance(RectangleSelections, transient=True) filters = List(Instance(BaseFilter)) figure = Instance(Figure, transient=True) data = Array def _filters_default(self): return [Rotate(), GaussianFilter()] def _analysis_default(self): return RectangleSelections() def _figure_default(self): def selection_callback(pos1, pos2): try: if pos1 == pos2: self.analysis.selection.set_from_points(pos1) else: self.analysis.selection.set_from_points(pos1, pos2) except: pass figure = Figure(process_selection=selection_callback) return figure @on_trait_change('filenames.selected') def open_image(self): data = imread(self.filenames.selected) for f in self.filters: data = f.process(data) self.data = data @on_trait_change('data,analysis.updated') def image_show(self): try: self.figure.plot_image(self.data) except: pass @on_trait_change('analysis.updated') def show_selection2(self): def plot(selection, color, index): s = selection x, y = list( map(lambda *args: args, s.top_left, s.top_right, s.bottom_right, s.bottom_left, s.top_left)) self.figure.plot_data(x, y, str(index), color) for i in range(len(self.analysis.selections) + 1): self.figure.del_plot(str(i)) for index, selection in enumerate(self.analysis.selections): if self.analysis.index == index: color = 'red' else: color = 'black' try: plot(selection, color, index) except: pass view = View( VSplit(HSplit(Item('figure', style='custom', width=0.6, height=0.7), Group(Item('analysis', style="custom", resizable=True, width=0.4, height=0.7, show_label=False), scrollable=True), show_labels=False), HSplit( Group( Item('filenames', style='custom', show_label=False, height=0.3)), Item('filters@', id='notebook', show_label=False, editor=ListEditor(use_notebook=True, deletable=False, selected='selected', export='DockWindowShell', page_name='.name_'))), show_labels=False), width=1000, height=800, resizable=True, )
menu=Menu(NewAction, Separator(), DeleteAction, Separator( ), RenameAction, Separator(), CopyAction, CutAction, PasteAction), view=View(['name', '|<']), add=[Employee]), TreeNode(node_for=[Employee], auto_open=True, label='name', menu=Menu( NewAction, Separator(), Action(name='Default title', action='object.default_title'), Action(name='Department', action='handler.employee_department(editor,object)'), Separator(), CopyAction, CutAction, PasteAction, Separator(), DeleteAction, Separator(), RenameAction), view=View(VSplit(HGroup('3', 'name'), HGroup('9', 'title'), HGroup('phone'), id='vsplit'), id='enthought.traits.ui.test.tree_editor_test.employee', dock='vertical')) ]) #------------------------------------------------------------------------------- # 'TreeHandler' class: #------------------------------------------------------------------------------- class TreeHandler(Handler): def employee_department(self, editor, object): dept = editor.get_parent(object) print '%s works in the %s department.' % (object.name, dept.name)
class ImageStackViewer(BaseDataViewer): plotdata = Instance(ArrayPlotData) plots = Dict # map of plot names to Plot.img_plot(..)[0] results current_slice = List([0, 0, 0]) traits_view = View( Tabbed( HSplit( Item('plot', editor=ComponentEditor(), show_label=False, resizable=True, label='View'), VSplit( Item('options', style='custom', show_label=False, resizable=True), Item('tasks', style='custom', show_label=False, label='Tasks')), ), Item('results', style='custom', show_label=False, label='Results'), ), ) def _complex_view_changed(self): self.reset() def _plotdata_default(self): arr = self.data plotdata = ArrayPlotData( zz=numpy.array([[0]]), z_x=[], z_y=[], y_x=[], y_z=[], x_y=[], x_z=[], ) plotdata.set_data('xy', arr[0]) plotdata.set_data('xz', arr[:, 0]) plotdata.set_data('zy', arr[:, :, 0].T) return plotdata def select_xy_slice(self, z): self.current_slice[0] = z data = self.get_data_slice(z, 0) points = self.get_points(z, 0) xdata = self.get_points_coords(z, 0, 2) ydata = self.get_points_coords(z, 0, 1) #xdata = [point.x for point in points] #ydata = [point.y for point in points] selections = [i for i, point in enumerate(points) if point.selected] self.plotdata.set_data('xy', data) self.plotdata.set_data('z_x', xdata) self.plotdata.set_data('z_y', ydata) self.plots['xyp'].index.metadata['selections'] = selections self.plots['xyp'].invalidate_and_redraw() self.plots['xy'].invalidate_and_redraw() def select_xz_slice(self, y): self.current_slice[1] = y data = self.get_data_slice(y, 1) points = self.get_points(y, 1) #xdata = [point.x for point in points] #zdata = [point.z for point in points] xdata = self.get_points_coords(y, 1, 2) zdata = self.get_points_coords(y, 1, 0) selections = [i for i, point in enumerate(points) if point.selected] self.plotdata.set_data('xz', data) self.plotdata.set_data('y_x', xdata) self.plotdata.set_data('y_z', zdata) self.plots['xzp'].index.metadata['selections'] = selections self.plots['xzp'].invalidate_and_redraw() self.plots['xz'].invalidate_and_redraw() def select_zy_slice(self, x): self.current_slice[2] = x data = self.get_data_slice(x, 2).T points = self.get_points(x, 2) #ydata = [point.y for point in points] #zdata = [point.z for point in points] ydata = self.get_points_coords(x, 2, 1) zdata = self.get_points_coords(x, 2, 0) selections = [i for i, point in enumerate(points) if point.selected] self.plotdata.set_data('zy', data) self.plotdata.set_data('x_y', ydata) self.plotdata.set_data('x_z', zdata) self.plots['zyp'].index.metadata['selections'] = selections self.plots['zyp'].invalidate_and_redraw() self.plots['zy'].invalidate_and_redraw() def redraw(self): for p in self.plots.values(): p.invalidate_and_redraw() def reset(self): self.reset_points() def reset_points(self): if self.plots: self.select_xy_slice(self.current_slice[0]) self.select_xz_slice(self.current_slice[1]) self.select_zy_slice(self.current_slice[2]) def _xyp_metadata_handler(self): z = self.current_slice[0] selections = self.plots['xyp'].index.metadata.get('selections', []) points = self.get_points(z, 0) changed = False for i, point in enumerate(points): old_value = point.selected new_value = i in selections if old_value == new_value: continue point.selected = new_value changed = True if changed: self.select_xz_slice(self.current_slice[1]) self.select_zy_slice(self.current_slice[2]) def _xzp_metadata_handler(self): y = self.current_slice[1] selections = self.plots['xzp'].index.metadata.get('selections', []) points = self.get_points(y, 1) changed = False for i, point in enumerate(points): old_value = point.selected new_value = i in selections if old_value == new_value: continue point.selected = new_value changed = True if changed: self.select_xy_slice(self.current_slice[0]) self.select_zy_slice(self.current_slice[2]) def _zyp_metadata_handler(self): x = self.current_slice[2] selections = self.plots['zyp'].index.metadata.get('selections', []) points = self.get_points(x, 2) changed = False for i, point in enumerate(points): old_value = point.selected new_value = i in selections if old_value == new_value: continue point.selected = new_value changed = True if changed: self.select_xy_slice(self.current_slice[0]) self.select_xz_slice(self.current_slice[1]) def get_plot(self): pixel_sizes = self.data_source.voxel_sizes shape = self.data.shape m = min(pixel_sizes) s = [int(d * sz / m) for d, sz in zip(shape, pixel_sizes)] if 1: # else physical aspect ratio is enabled ss = max(s) / 4 s = [max(s, ss) for s in s] plot_sizes = dict(xy=(s[2], s[1]), xz=(s[2], s[0]), zy=(s[0], s[1]), zz=(s[0], s[0])) plots = GridContainer(shape=(2, 2), spacing=(3, 3), padding=50, aspect_ratio=1) pxy = Plot( self.plotdata, padding=1, fixed_preferred_size=plot_sizes['xy'], x_axis=PlotAxis(orientation='top'), ) pxz = Plot( self.plotdata, padding=1, fixed_preferred_size=plot_sizes['xz'], ) pzy = Plot( self.plotdata, padding=1, fixed_preferred_size=plot_sizes['zy'], #orientation = 'v', # cannot use 'v' because of img_plot assumes row-major ordering x_axis=PlotAxis(orientation='top'), y_axis=PlotAxis(orientation='right'), ) pzz = Plot(self.plotdata, padding=1, fixed_preferred_size=plot_sizes['zz']) plots.add(pxy, pzy, pxz, pzz) self.plots = dict( xy=pxy.img_plot('xy', colormap=bone)[0], xz=pxz.img_plot('xz', colormap=bone)[0], zy=pzy.img_plot('zy', colormap=bone)[0], zz=pzz.img_plot('zz')[0], xyp=pxy.plot(('z_x', 'z_y'), type='scatter', color='orange', marker='circle', marker_size=3, selection_marker_size=3, selection_marker='circle')[0], xzp=pxz.plot(('y_x', 'y_z'), type='scatter', color='orange', marker='circle', marker_size=3, selection_marker_size=3, selection_marker='circle')[0], zyp=pzy.plot(('x_z', 'x_y'), type='scatter', color='orange', marker='circle', marker_size=3, selection_marker_size=3, selection_marker='circle')[0], ) for p in ['xy', 'xz', 'zy']: self.plots[p].overlays.append(ZoomTool(self.plots[p])) self.plots[p].tools.append( PanTool(self.plots[p], drag_button='right')) imgtool = ImageInspectorTool(self.plots[p]) self.plots[p].tools.append(imgtool) overlay = ImageInspectorOverlay(component=self.plots[p], bgcolor='white', image_inspector=imgtool) self.plots['zz'].overlays.append(overlay) self.plots[p + 'p'].tools.append( ScatterInspector(self.plots[p + 'p'], selection_mode='toggle')) self.plots['xyp'].index.on_trait_change(self._xyp_metadata_handler, 'metadata_changed') self.plots['xzp'].index.on_trait_change(self._xzp_metadata_handler, 'metadata_changed') self.plots['zyp'].index.on_trait_change(self._zyp_metadata_handler, 'metadata_changed') plot = HPlotContainer() # todo: add colormaps plot.add(plots) return plot
class Application(HasTraits): scene = Instance(MlabSceneModel, (), editor=SceneEditor()) # The mayavi engine view. engine_view = Instance(EngineView) coils = List(Instance(Loop, (), allow_none=False), editor=ListEditor(style='custom'), value=[ Loop(position=(0, 0, -0.05), ), Loop(position=(0, 0, 0.05), ), ]) Bx = Array(value=np.zeros_like(X)) By = Array(value=np.zeros_like(X)) Bz = Array(value=np.zeros_like(X)) Bnorm = Array(value=np.zeros_like(X)) vector_field = None def __init__(self, **traits): HasTraits.__init__(self, **traits) self.engine_view = EngineView(engine=self.scene.engine) @on_trait_change('scene.activated,coils') def init_view(self): if self.scene._renderer is not None: self.scene.scene_editor.background = (0, 0, 0) for coil in self.coils: coil.app = self coil.display() self.visualize_field() def visualize_field(self): self.Bx = np.zeros_like(X) self.By = np.zeros_like(X) self.Bz = np.zeros_like(X) self.Bnorm = np.zeros_like(X) self.scene.scene.disable_render = True for coil in self.coils: self.Bx += coil.Bx self.By += coil.By self.Bz += coil.Bz self.Bnorm = np.sqrt(self.Bx**2 + self.By**2 + self.Bz**2) if self.vector_field is None: self.vector_field = self.scene.mlab.pipeline.vector_field( X, Y, Z, self.Bx, self.By, self.Bz, scalars=self.Bnorm, name='B field') vectors = self.scene.mlab.pipeline.vectors( self.vector_field, mode='arrow', resolution=10, mask_points=6, colormap='YlOrRd', scale_factor=2 * np.abs(X[0, 0, 0] - X[1, 1, 1])) vectors.module_manager.vector_lut_manager.reverse_lut = True vectors.glyph.mask_points.random_mode = False self.scene.mlab.axes() self.scp = self.scene.mlab.pipeline.scalar_cut_plane( self.vector_field, colormap='hot') else: # Modify in place the data source. The visualization will # update automaticaly self.vector_field.mlab_source.set(u=self.Bx, v=self.By, w=self.Bz, scalars=self.Bnorm) self.scene.scene.disable_render = False view = View( HSplit(VSplit(Item(name='engine_view', style='custom', resizable=True), Item('coils', springy=True), show_labels=False), 'scene', show_labels=False), resizable=True, title='Coils...', height=0.8, width=0.8, )
class LiveSearch ( HasTraits ): # The currenty root directory being searched: root = Directory( getcwd(), entries = 10 ) # Should sub directories be included in the search: recursive = Bool( True ) # The file types to include in the search: file_type = Enum( 'Python', 'C', 'C++', 'Java', 'Ruby' ) # The current search string: search = Str # Is the search case sensitive? case_sensitive = Bool( False ) # The live search table filter: filter = Property # Instance( TableFilter ) # The current list of source files being searched: source_files = Property # List( SourceFile ) # The currently selected source file: selected = Any # Instance( SourceFile ) # The contents of the currently selected source file: selected_contents = Property # List( Str ) # The currently selected match: selected_match = Int # The text line corresponding to the selected match: selected_line = Property # Int # The full name of the currently selected source file: selected_full_name = Property # File # The list of marked lines for the currently selected file: mark_lines = Property # List( Int ) # Summary of current number of files and matches: summary = Property # Str #-- Traits UI Views -------------------------------------------------------- view = View( VGroup( HGroup( Item( 'root', id = 'root', label = 'Path', width = 0.5 ), Item( 'recursive' ), Item( 'file_type', label = 'Type' ), Item( 'search', id = 'search', width = 0.5, editor = HistoryEditor( auto_set = True ) ), Item( 'case_sensitive' ) ), VSplit( VGroup( Item( 'summary', editor = TitleEditor() ), Item( 'source_files', id = 'source_files', editor = table_editor ), dock = 'horizontal', show_labels = False ), VGroup( HGroup( Item( 'selected_full_name', editor = TitleEditor(), springy = True ), Item( 'selected_full_name', editor = DNDEditor(), tooltip = 'Drag this file' ), show_labels = False ), Item( 'selected_contents', style = 'readonly', editor = CodeEditor( mark_lines = 'mark_lines', line = 'selected_line', selected_line = 'selected_line' ) ), dock = 'horizontal', show_labels = False ), id = 'splitter' ) ), title = 'Live File Search', id = 'enthought.examples.demo.Advanced.' 'Table_editor_with_live_search_and_cell_editor.LiveSearch', width = 0.75, height = 0.67, resizable = True ) #-- Property Implementations ----------------------------------------------- @property_depends_on( 'search, case_sensitive' ) def _get_filter ( self ): if len( self.search ) == 0: return lambda x: True return lambda x: len( x.matches ) > 0 @property_depends_on( 'root, recursive, file_type' ) def _get_source_files ( self ): root = self.root if root == '': root = getcwd() file_types = FileTypes[ self.file_type ] if self.recursive: result = [] for dir_path, dir_names, file_names in walk( root ): for file_name in file_names: if splitext( file_name )[1] in file_types: result.append( SourceFile( live_search = self, full_name = join( dir_path, file_name ) ) ) return result return [ SourceFile( live_search = self, full_name = join( root, file_name ) ) for file_name in listdir( root ) if splitext( file_name )[1] in file_types ] @property_depends_on( 'selected' ) def _get_selected_contents ( self ): if self.selected is None: return '' return ''.join( self.selected.contents ) @property_depends_on( 'selected' ) def _get_mark_lines ( self ): if self.selected is None: return [] return [ int( match.split( ':', 1 )[0] ) for match in self.selected.matches ] @property_depends_on( 'selected, selected_match' ) def _get_selected_line ( self ): selected = self.selected if (selected is None) or (len( selected.matches ) == 0): return 1 return int( selected.matches[ self.selected_match - 1 ].split( ':', 1 )[0] ) @property_depends_on( 'selected' ) def _get_selected_full_name ( self ): if self.selected is None: return '' return self.selected.full_name @property_depends_on( 'source_files, search, case_sensitive' ) def _get_summary ( self ): source_files = self.source_files search = self.search if search == '': return 'A total of %d files.' % len( source_files ) files = 0 matches = 0 for source_file in source_files: n = len( source_file.matches ) if n > 0: files += 1 matches += n return 'A total of %d files with %d files containing %d matches.' % ( len( source_files ), files, matches ) #-- Traits Event Handlers -------------------------------------------------- def _selected_changed ( self ): self.selected_match = 1 def _source_files_changed ( self ): if len( self.source_files ) > 0: self.selected = self.source_files[0] else: self.selected = None
class TriangleWave(HasTraits): # 指定三角波的最窄和最宽范围,由于Range类型不能将常数和Traits属性名混用 # 所以定义这两个值不变的Trait属性 low = Float(0.02) hi = Float(1.0) # 三角波形的宽度 wave_width = Range("low", "hi", 0.5) # 三角波的顶点C的x轴坐标 length_c = Range("low", "wave_width", 0.5) # 三角波的定点的y轴坐标 height_c = Float(1.0) # FFT计算所使用的取样点数,这里用一个Enum类型的属性以供用户从列表中选择 fftsize = Enum([(2**x) for x in range(6, 12)]) # FFT频谱图的x轴上限值 fft_graph_up_limit = Range(0, 400, 20) # 用于显示FFT的结果 peak_list = Str # 采用多少个频率合成三角波 N = Range(1, 40, 4) # 保存绘图数据的对象 plot_data = Instance(AbstractPlotData) # 绘制波形图的容器 plot_wave = Instance(Component) # 绘制FFT频谱图的容器 plot_fft = Instance(Component) # 包括两个绘图的容器 container = Instance(Component) # 设置用户界面的视图, 注意一定要指定窗口的大小,这样绘图容器才能正常初始化 view = View(HSplit( VSplit( VGroup(Item("wave_width", editor=scrubber, label="波形宽度"), Item("length_c", editor=scrubber, label="最高点x坐标"), Item("height_c", editor=scrubber, label="最高点y坐标"), Item("fft_graph_up_limit", editor=scrubber, label="频谱图范围"), Item("fftsize", label="FFT点数"), Item("N", label="合成波频率数")), Item("peak_list", style="custom", show_label=False, width=100, height=250)), VGroup(Item("container", editor=ComponentEditor(size=(600, 300)), show_label=False), orientation="vertical")), resizable=True, width=800, height=600, title="三角波FFT演示") # 创建绘图的辅助函数,创建波形图和频谱图有很多类似的地方,因此单独用一个函数以 # 减少重复代码 def _create_plot(self, data, name, type="line"): p = Plot(self.plot_data) p.plot(data, name=name, title=name, type=type) p.tools.append(PanTool(p)) zoom = ZoomTool(component=p, tool_mode="box", always_on=False) p.overlays.append(zoom) p.title = name return p def __init__(self): # 首先需要调用父类的初始化函数 super(TriangleWave, self).__init__() # 创建绘图数据集,暂时没有数据因此都赋值为空,只是创建几个名字,以供Plot引用 self.plot_data = ArrayPlotData(x=[], y=[], f=[], p=[], x2=[], y2=[]) # 创建一个垂直排列的绘图容器,它将频谱图和波形图上下排列 self.container = VPlotContainer() # 创建波形图,波形图绘制两条曲线: 原始波形(x,y)和合成波形(x2,y2) self.plot_wave = self._create_plot(("x", "y"), "Triangle Wave") self.plot_wave.plot(("x2", "y2"), color="red") # 创建频谱图,使用数据集中的f和p self.plot_fft = self._create_plot(("f", "p"), "FFT", type="scatter") # 将两个绘图容器添加到垂直容器中 self.container.add(self.plot_wave) self.container.add(self.plot_fft) # 设置 self.plot_wave.x_axis.title = "Samples" self.plot_fft.x_axis.title = "Frequency pins" self.plot_fft.y_axis.title = "(dB)" # 改变fftsize为1024,因为Enum的默认缺省值为枚举列表中的第一个值 self.fftsize = 1024 # FFT频谱图的x轴上限值的改变事件处理函数,将最新的值赋值给频谱图的响应属性 def _fft_graph_up_limit_changed(self): self.plot_fft.x_axis.mapper.range.high = self.fft_graph_up_limit def _N_changed(self): self.plot_sin_combine() # 多个trait属性的改变事件处理函数相同时,可以用@on_trait_change指定 @on_trait_change("wave_width, length_c, height_c, fftsize") def update_plot(self): # 计算三角波 global y_data x_data = np.arange(0, 1.0, 1.0 / self.fftsize) func = self.triangle_func() # 将func函数的返回值强制转换成float64 y_data = np.cast["float64"](func(x_data)) # 计算频谱 fft_parameters = np.fft.fft(y_data) / len(y_data) # 计算各个频率的振幅 fft_data = np.clip( 20 * np.log10(np.abs(fft_parameters))[:self.fftsize / 2 + 1], -120, 120) # 将计算的结果写进数据集 self.plot_data.set_data("x", np.arange(0, self.fftsize)) # x坐标为取样点 self.plot_data.set_data("y", y_data) self.plot_data.set_data("f", np.arange(0, len(fft_data))) # x坐标为频率编号 self.plot_data.set_data("p", fft_data) # 合成波的x坐标为取样点,显示2个周期 self.plot_data.set_data("x2", np.arange(0, 2 * self.fftsize)) # 更新频谱图x轴上限 self._fft_graph_up_limit_changed() # 将振幅大于-80dB的频率输出 peak_index = (fft_data > -80) peak_value = fft_data[peak_index][:20] result = [] for f, v in zip(np.flatnonzero(peak_index), peak_value): result.append("%s : %s" % (f, v)) self.peak_list = "\n".join(result) # 保存现在的fft计算结果,并计算正弦合成波 self.fft_parameters = fft_parameters self.plot_sin_combine() # 计算正弦合成波,计算2个周期 def plot_sin_combine(self): index, data = fft_combine(self.fft_parameters, self.N, 2) self.plot_data.set_data("y2", data) # 返回一个ufunc计算指定参数的三角波 def triangle_func(self): c = self.wave_width c0 = self.length_c hc = self.height_c def trifunc(x): x = x - int(x) # 三角波的周期为1,因此只取x坐标的小数部分进行计算 if x >= c: r = 0.0 elif x < c0: r = x / c0 * hc else: r = (c - x) / (c - c0) * hc return r # 用trifunc函数创建一个ufunc函数,可以直接对数组进行计算, 不过通过此函数 # 计算得到的是一个Object数组,需要进行类型转换 return np.frompyfunc(trifunc, 1, 1)
), resizable = True, width = 400, height = 150, title = "水平分组(带调节栏)" ) view4 = View( VSplit( VGroup( Item(name = 'employee_number', label='编号'), Item(name = 'department', label="部门", tooltip="在哪个部门干活"), Item(name = 'last_name', label="姓"), Item(name = 'first_name', label="名"), show_border = True, scrollable = True ), VGroup( Item(name = 'salary', label="工资"), Item(name = 'bonus', label="奖金"), show_border = True, scrollable = True ), ), resizable = True, width = 200, height = 300, title = "垂直分组(带调节栏)" ) sam = SimpleEmployee() sam.edit_traits(view=view1)
class PlotOMatic(HasTraits): io_driver_list = Instance(IODriverList) variables = Instance(Variables) viewers = Instance(Viewers) selected_viewer = Instance(Viewer) handler = PlotOMaticHandler() viewer_node = TreeNode(node_for=[Viewer], auto_open=True, label='name', menu=Menu(handler.remove_viewer_action), icon_path='icons/', icon_item='plot.png') tree_editor = TreeEditor(nodes=[ TreeNode( node_for=[IODriverList], auto_open=True, children='io_drivers', label='=Input Drivers', menu=Menu(handler.refresh_tree_action, handler.add_io_driver_actions_menu), view=View(), ), TreeNode(node_for=[IODriver], auto_open=True, children='_decoders', label='name', add=[DataDecoder], menu=Menu(handler.remove_io_driver_action, handler.refresh_tree_action, handler.add_decoder_actions_menu), icon_path='icons/', icon_open='input.png', icon_group='input.png'), TreeNode(node_for=[DataDecoder], auto_open=True, children='', label='name', menu=Menu(handler.refresh_tree_action, handler.remove_decoder_action), icon_path='icons/', icon_item='decoder.png'), TreeNode(node_for=[IODriverList], auto_open=True, children='viewers', label='=Viewers', menu=Menu(handler.refresh_tree_action, handler.add_viewer_actions_menu), view=View()), viewer_node ], hide_root=True, orientation='vertical') view = View(HSplit( Item(name='io_driver_list', editor=tree_editor, resizable=True, show_label=False, width=.32), VSplit( Item(name='selected_viewer', style='custom', resizable=True, show_label=False, editor=InstanceEditor(view='view')), Item(name='variables', show_label=False, style='custom', height=.3))), menubar=MenuBar(handler.file_menu, handler.data_menu), title='Plot-o-matic', resizable=True, width=1000, height=600, handler=PlotOMaticHandler()) def __init__(self, **kwargs): HasTraits.__init__(self, **kwargs) self.viewer_node.on_select = self.click_viewer def click_viewer(self, viewer): self.selected_viewer = viewer self.viewers.select_viewer(viewer) def start(self): self.io_driver_list.start_all() self.viewers.start() def stop(self): self.viewers.stop() self.io_driver_list.stop_all() def get_config(self): config = {} config['io_drivers'] = self.io_driver_list.get_config() config['viewers'] = self.viewers.get_config() return config def set_config(self, config): if 'io_drivers' in config: self.io_driver_list.set_config(config['io_drivers']) if 'viewers' in config: self.viewers.set_config(config['viewers']) self.variables.clear()
class Mayavi(HasTraits): # The scene model. scene = Instance(MlabSceneModel, ()) # The mayavi engine view. engine_view = Instance(EngineView) # The current selection in the engine tree view. current_selection = Property ###################### view = View(HSplit( VSplit( Item(name='engine_view', style='custom', resizable=True, show_label=False), Item(name='current_selection', editor=InstanceEditor(), enabled_when='current_selection is not None', style='custom', springy=True, show_label=False), ), Item(name='scene', editor=SceneEditor(), show_label=False, resizable=True, height=500, width=500), ), resizable=True, scrollable=True) def __init__(self, **traits): HasTraits.__init__(self, **traits) self.engine_view = EngineView(engine=self.scene.engine) # Hook up the current_selection to change when the one in the engine # changes. This is probably unnecessary in Traits3 since you can show # the UI of a sub-object in T3. self.scene.engine.on_trait_change(self._selection_change, 'current_selection') self.generate_data_mayavi() def generate_data_mayavi(self): """Shows how you can generate data using mayavi instead of mlab.""" from enthought.mayavi.sources.api import ParametricSurface from enthought.mayavi.modules.api import Outline, Surface e = self.scene.engine s = ParametricSurface() e.add_source(s) e.add_module(Outline()) e.add_module(Surface()) def _selection_change(self, old, new): self.trait_property_changed('current_selection', old, new) def _get_current_selection(self): return self.scene.engine.current_selection