def _do_plot_boilerplate(kwargs, image=False): """ Used by various plotting functions. Checks/handles hold state, returns a Plot object for the plotting function to use. """ if kwargs.has_key("hold"): hold(kwargs["hold"]) del kwargs["hold"] # Check for an active window; if none, open one. if len(session.windows) == 0: if image: win = session.new_window(is_image=True) activate(win) else: figure() cont = session.active_window.get_container() if not cont: cont = Plot(session.data) session.active_window.set_container(cont) existing_tools = [type(t) for t in (cont.tools + cont.overlays)] if not PanTool in existing_tools: cont.tools.append(PanTool(cont)) if not ZoomTool in existing_tools: cont.overlays.append(ZoomTool(cont, tool_mode="box", always_on=True, drag_button="right")) if not session.hold: cont.delplot(*cont.plots.keys()) return cont
class ImagePlot(HasTraits): #plot = Instance(Plot) # traits_view = View( # Group(Item('container', # editor=ComponentEditor(), # show_label=False)), # width=500, height=500, # buttons=NoButtons, # resizable=True, title="QTLab Analysis Plot") # Item('plot', editor=ComponentEditor(), show_label=False), # width=500, height=500, resizable=True, title="QTLab Analysis Plot") # def __init__(self, title, xtitle, x, ytitle, y, z): # super(ImagePlot, self).__init__() # self.create_plot(title, xtitle, x, ytitle, y, z) def _create_window(self, title, xtitle, x, ytitle, y, z): ''' - Left-drag pans the plot. - Mousewheel up and down zooms the plot in and out. - Pressing "z" brings up the Zoom Box, and you can click-drag a rectangular region to zoom. If you use a sequence of zoom boxes, pressing alt-left-arrow and alt-right-arrow moves you forwards and backwards through the "zoom history". ''' self._plotname = title # Create window self.data = ArrayPlotData() self.plot = Plot(self.data) self.update_plot(x, y, z) self.plot.title = title self.plot.x_axis.title = xtitle self.plot.y_axis.title = ytitle cmap_renderer = self.plot.plots[self._plotname][0] # Create colorbar self._create_colorbar() self._colorbar.plot = cmap_renderer self._colorbar.padding_top = self.plot.padding_top self._colorbar.padding_bottom = self.plot.padding_bottom # Add some tools self.plot.tools.append(PanTool(self.plot, constrain_key="shift")) self.plot.overlays.append(ZoomTool(component=self.plot, tool_mode="box", always_on=False)) # selection = ColormappedSelectionOverlay(cmap_renderer, fade_alpha=0.35, selection_type="mask") # cmap_renderer.overlays.append(selection) # Create a container to position the plot and the colorbar side-by-side container = HPlotContainer(use_backbuffer = True) container.add(self.plot) container.add(self._colorbar) self.container = container # Return a window containing our plot container return Window(self, -1, component=container) def update_plot(self, x, y, z): self.data.set_data('x', x) self.data.set_data('y', y) self.data.set_data('z', z) if self.plot.plots.has_key(self._plotname): self.plot.delplot(self._plotname) # determine correct bounds xstep = (x.max() - x.min())/(len(x)-1) ystep = (y.max() - y.min())/(len(y)-1) x0, x1 = x.min() - xstep/2, x.max() + xstep/2 y0, y1 = y.min() - ystep/2, y.max() + ystep/2 self.plot.img_plot('z', name = self._plotname, xbounds = (x0, x1), ybounds = (y0, y1), colormap = jet) # self.plot.plot(("x", "y", "z"), # type = "img_plot", # name = self._plotname, # color_mapper = jet, # marker = "square", # fill_alpha = 0.5, # marker_size = 6, # outline_color = "black", # border_visible = True, # bgcolor = "white") def _create_colorbar(self): cmap = self.plot.color_mapper self._colorbar = ColorBar(index_mapper=LinearMapper(range=cmap.range), color_mapper=cmap, orientation='v', resizable='v', width=30, padding=30)
class FiberView( HasTraits ): timer = Instance( Timer ) # model = FiberModel(options) plot_data = Instance( ArrayPlotData ) plot = Instance( Plot ) start_stop = Button() exit = Button() # Default TraitsUI view traits_view = View( Item('plot', editor=ComponentEditor(), show_label=False), # Items HGroup( spring, Item( "start_stop", show_label = False ), Item( "exit", show_label = False ), spring), HGroup( spring ), # GUI window resizable = True, width = 1000, height = 700, kind = 'live' ) def __init__(self, options, **kwtraits): super( FiberView, self).__init__(**kwtraits ) self.model = FiberModel(options) # debugging self.debug = options.debug self.model.debug = options.debug # timing parameters self.max_packets = options.max_packets self.hertz = options.hertz # extend options to model self.model.max_packets = options.max_packets self.model.preallocate_arrays() self.model.num_analog_channels = options.num_analog_channels # generate traits plot self.plot_data = ArrayPlotData( x = self.model._tdata, y = self.model._ydata ) self.plot = Plot( self.plot_data ) renderer = self.plot.plot(("x", "y"), type="line", name='old', color="green")[0] # self.plot.delplot('old') # recording flags self.model.recording = False self.model.trialEnded = True print 'Viewer initialized.' # should we wait for a ttl input to start? if options.ttl_start: self.model.ttl_start = True self.ttl_received = False # initialize FIO0 for TTL input self.FIO0_DIR_REGISTER = 6100 self.FIO0_STATE_REGISTER = 6000 self.model.labjack.writeRegister(self.FIO0_DIR_REGISTER, 0) # Set FIO0 low # initialize output array self.out_arr = None # keep track of number of runs self.run_number = 0 self.timer = Timer(self.model.dt, self.time_update) # update every 1 ms def run( self ): self._plot_update() self.model._get_current_data() def time_update( self ): """ Callback that gets called on a timer to get the next data point over the labjack """ # print "time_update" # print "self.model.ttl_start", self.model.ttl_start # print "self.ttl_received", self.ttl_received # print "self.model.recording", self.model.recording if self.model.ttl_start and not self.ttl_received: ttl = self.check_for_ttl() if ttl: self.ttl_received = True # self.model.recording = True # self.model.trialEnded = False self._start_stop_fired() if self.model.recording and not self.model.ttl_start: self.run() elif self.model.ttl_start: if self.model.recording and self.ttl_received: self.run() # elif self.model.recording: # self._start_stop_fired() else: if self.debug: pass #print "--timer tic--" pass def check_for_ttl(self): start_ttl = self.model.labjack.readRegister(self.FIO0_STATE_REGISTER) # print "start_ttl: ", start_ttl return start_ttl def clean_time_series(self, time_series, blip_thresh = 10.0): """ Removes blips, NAs, etc. """ blip_idxs = time_series > blip_thresh time_series[blip_idxs] = np.median(time_series) return time_series def _plot_update( self ): num_display_points = 100*25 # For 1000 Hz if self.model.master_index > num_display_points: disp_begin = self.model.master_index - num_display_points disp_end = self.model.master_index print 'disp_begin', disp_begin print 'disp_end', disp_end ydata = self.clean_time_series( np.array(self.model._ydata[disp_begin:disp_end]) ) xdata = np.array(self.model._tdata[disp_begin:disp_end]) self.plot_data.set_data("y", ydata) self.plot_data.set_data("x", xdata) else: self.plot_data.set_data( "y", self.clean_time_series( self.model._ydata[0:self.model.master_index] )) self.plot_data.set_data( "x", self.model._tdata[0:self.model.master_index] ) self.plot = Plot( self.plot_data ) # self.plot.delplot('old') the_plot = self.plot.plot(("x", "y"), type="line", name = 'old', color="green")[0] self.plot.request_redraw() # Note: These should be moved to a proper handler (ModelViewController) def _start_stop_fired( self ): self.model.start_time = time.time() self.model.recording = not self.model.recording self.model.trialEnded = not self.model.trialEnded if self.model.trialEnded: self.save() def _exit_fired(self): print "Closing connection to LabJack..." self.ttl_start = False self.recording = False self.model.sdr.running = False self.model.recording = False # self.model.labjack.streamStop() self.model.labjack.close() print "connection closed. Safe to close..." #raise SystemExit #sys.exit() def save( self ): print "Saving!" # Finally, construct and save full data array print "Saving acquired data..." for i in xrange( len( self.model.data ) ): new_array = 1 block = self.model.data[i] for k in self.model.result.keys(): print k if k != 0: if new_array == 1: array = np.array(block[k]) array.shape = (len(array),1) new_array = 0 else: new_data = np.array(block[k]) new_data.shape = (len(block[k]),1) # if new_data is short by one, fill in with last entry if new_data.shape[0] < array.shape[0]: new_data = np.append( new_data, new_data[-1] ) new_data.shape = (new_data.shape[0], 1) print "Appended point to new_data, shape now:",new_data.shape if new_data.shape[0] > array.shape[0]: new_data = new_data[:-1] print "Removed point from new_data, shape now:",new_data.shape print "array shape, new_data shape:", array.shape, new_data.shape array = np.hstack((array, new_data )) if i == 0: self.out_arr = array print "Array shape:", self.out_arr.shape else: self.out_arr = np.vstack( (self.out_arr, array) ) print "Array shape:", self.out_arr.shape date = time.localtime() outfile = self.model.savepath + self.model.filename outfile += str(date[0]) + '_' + str(date[1]) + '_' + str(date[2]) + '_' outfile += str(date[3]) + ':' + str(date[4]) + '_run_number_' + str(self.run_number) np.savez(outfile, data=self.out_arr, time_stamps=self.model._tdata) # time_outfile = outfile + '_t' # np.savez(time_outfile, self.model._tdata) print "Saved ", outfile # Plot the data collected this last run self.plot_last_data() # clean up self.reset_variables() def reset_variables(self): self.out_arr = None self.ttl_received = False self.run_number += 1 self.model.recording = False self.trialEnded = True self.plot.delplot('old') def plot_last_data(self): import pylab as pl if self.out_arr.shape[1] == 4: pl.figure() pl.subplot(411) pl.plot(self.out_arr[:,0]) pl.subplot(412) pl.plot(self.out_arr[:,1]) pl.subplot(413) pl.plot(self.out_arr[:,2]) pl.subplot(414) pl.plot(self.out_arr[:,3]) pl.show()
class ImagePlot(HasTraits): #plot = Instance(Plot) # traits_view = View( # Group(Item('container', # editor=ComponentEditor(), # show_label=False)), # width=500, height=500, # buttons=NoButtons, # resizable=True, title="QTLab Analysis Plot") # Item('plot', editor=ComponentEditor(), show_label=False), # width=500, height=500, resizable=True, title="QTLab Analysis Plot") # def __init__(self, title, xtitle, x, ytitle, y, z): # super(ImagePlot, self).__init__() # self.create_plot(title, xtitle, x, ytitle, y, z) def _create_window(self, title, xtitle, x, ytitle, y, z): ''' - Left-drag pans the plot. - Mousewheel up and down zooms the plot in and out. - Pressing "z" brings up the Zoom Box, and you can click-drag a rectangular region to zoom. If you use a sequence of zoom boxes, pressing alt-left-arrow and alt-right-arrow moves you forwards and backwards through the "zoom history". ''' self._plotname = title # Create window self.data = ArrayPlotData() self.plot = Plot(self.data) self.update_plot(x, y, z) self.plot.title = title self.plot.x_axis.title = xtitle self.plot.y_axis.title = ytitle cmap_renderer = self.plot.plots[self._plotname][0] # Create colorbar self._create_colorbar() self._colorbar.plot = cmap_renderer self._colorbar.padding_top = self.plot.padding_top self._colorbar.padding_bottom = self.plot.padding_bottom # Add some tools self.plot.tools.append(PanTool(self.plot, constrain_key="shift")) self.plot.overlays.append( ZoomTool(component=self.plot, tool_mode="box", always_on=False)) # selection = ColormappedSelectionOverlay(cmap_renderer, fade_alpha=0.35, selection_type="mask") # cmap_renderer.overlays.append(selection) # Create a container to position the plot and the colorbar side-by-side container = HPlotContainer(use_backbuffer=True) container.add(self.plot) container.add(self._colorbar) self.container = container # Return a window containing our plot container return Window(self, -1, component=container) def update_plot(self, x, y, z): self.data.set_data('x', x) self.data.set_data('y', y) self.data.set_data('z', z) if self.plot.plots.has_key(self._plotname): self.plot.delplot(self._plotname) # determine correct bounds xstep = (x.max() - x.min()) / (len(x) - 1) ystep = (y.max() - y.min()) / (len(y) - 1) x0, x1 = x.min() - xstep / 2, x.max() + xstep / 2 y0, y1 = y.min() - ystep / 2, y.max() + ystep / 2 self.plot.img_plot('z', name=self._plotname, xbounds=(x0, x1), ybounds=(y0, y1), colormap=jet) # self.plot.plot(("x", "y", "z"), # type = "img_plot", # name = self._plotname, # color_mapper = jet, # marker = "square", # fill_alpha = 0.5, # marker_size = 6, # outline_color = "black", # border_visible = True, # bgcolor = "white") def _create_colorbar(self): cmap = self.plot.color_mapper self._colorbar = ColorBar(index_mapper=LinearMapper(range=cmap.range), color_mapper=cmap, orientation='v', resizable='v', width=30, padding=30)
class FiberView( HasTraits ): timer = Instance( Timer ) # model = FiberModel(options) plot_data = Instance( ArrayPlotData ) plot = Instance( Plot ) start_stop = Button() exit = Button() # Default TraitsUI view traits_view = View( Item('plot', editor=ComponentEditor(), show_label=False), # Items HGroup( spring, Item( "start_stop", show_label = False ), Item( "exit", show_label = False ), spring), HGroup( spring ), # GUI window resizable = True, width = 1000, height = 700, kind = 'live' ) def __init__(self, options, **kwtraits): super( FiberView, self).__init__(**kwtraits ) self.model = FiberModel(options) # debugging self.debug = options.debug self.model.debug = options.debug # timing parameters self.max_packets = options.max_packets self.hertz = options.hertz # extend options to model self.model.max_packets = options.max_packets self.model.preallocate_arrays() self.model.num_analog_channels = options.num_analog_channels # generate traits plot self.plot_data = ArrayPlotData( x = self.model._tdata, y = self.model._ydata ) self.plot = Plot( self.plot_data ) renderer = self.plot.plot(("x", "y"), type="line", name='old', color="green")[0] # self.plot.delplot('old') # recording flags self.model.recording = False self.model.trialEnded = True print 'Viewer initialized.' # should we wait for a ttl input to start? if options.ttl_start: self.model.ttl_start = True self.ttl_received = False # initialize FIO0 for TTL input self.FIO0_DIR_REGISTER = 6100 self.FIO0_STATE_REGISTER = 6000 self.model.labjack.writeRegister(self.FIO0_DIR_REGISTER, 0) # Set FIO0 low # initialize output array self.out_arr = None # keep track of number of runs self.run_number = 0 self.timer = Timer(self.model.dt, self.time_update) # update every 1 ms def run( self ): self._plot_update() self.model._get_current_data() def time_update( self ): """ Callback that gets called on a timer to get the next data point over the labjack """ # print "time_update" # print "self.model.ttl_start", self.model.ttl_start # print "self.ttl_received", self.ttl_received # print "self.model.recording", self.model.recording if self.model.ttl_start and not self.ttl_received: ttl = self.check_for_ttl() if ttl: self.ttl_received = True # self.model.recording = True # self.model.trialEnded = False self._start_stop_fired() if self.model.recording and not self.model.ttl_start: self.run() elif self.model.ttl_start: if self.model.recording and self.ttl_received: self.run() # elif self.model.recording: # self._start_stop_fired() else: if self.debug: pass #print "--timer tic--" pass def check_for_ttl(self): start_ttl = self.model.labjack.readRegister(self.FIO0_STATE_REGISTER) # print "start_ttl: ", start_ttl return start_ttl def clean_time_series(self, time_series, blip_thresh = 10.0): """ Removes blips, NAs, etc. """ blip_idxs = time_series > blip_thresh time_series[blip_idxs] = np.median(time_series) return time_series def _plot_update( self ): num_display_points = 100*25 # For 1000 Hz if self.model.master_index > num_display_points: disp_begin = self.model.master_index - num_display_points disp_end = self.model.master_index # print 'disp_begin', disp_begin # print 'disp_end', disp_end ydata = self.clean_time_series( np.array(self.model._ydata[disp_begin:disp_end]) ) xdata = np.array(self.model._tdata[disp_begin:disp_end]) self.plot_data.set_data("y", ydata) self.plot_data.set_data("x", xdata) else: self.plot_data.set_data( "y", self.clean_time_series( self.model._ydata[0:self.model.master_index] )) self.plot_data.set_data( "x", self.model._tdata[0:self.model.master_index] ) self.plot = Plot( self.plot_data ) # self.plot.delplot('old') the_plot = self.plot.plot(("x", "y"), type="line", name = 'old', color="green")[0] self.plot.request_redraw() # Note: These should be moved to a proper handler (ModelViewController) def _start_stop_fired( self ): self.model.start_time = time.time() self.model.recording = not self.model.recording self.model.trialEnded = not self.model.trialEnded if self.model.trialEnded: self.save() #Quickly turn LED off to signal button push self.model.start_LED() def _exit_fired(self): print "Closing connection to LabJack..." self.ttl_start = False self.recording = False self.model.sdr.running = False self.model.recording = False # self.model.labjack.streamStop() self.model.labjack.close() print "connection closed. Safe to close..." #raise SystemExit #sys.exit() def save( self ): print "Saving!" # Finally, construct and save full data array print "Saving acquired data..." for i in xrange( len( self.model.data ) ): new_array = 1 block = self.model.data[i] for k in self.model.result.keys(): print k if k != 0: if new_array == 1: array = np.array(block[k]) array.shape = (len(array),1) new_array = 0 else: new_data = np.array(block[k]) new_data.shape = (len(block[k]),1) # if new_data is short by one, fill in with last entry if new_data.shape[0] < array.shape[0]: new_data = np.append( new_data, new_data[-1] ) new_data.shape = (new_data.shape[0], 1) print "Appended point to new_data, shape now:",new_data.shape if new_data.shape[0] > array.shape[0]: new_data = new_data[:-1] print "Removed point from new_data, shape now:",new_data.shape print "array shape, new_data shape:", array.shape, new_data.shape array = np.hstack((array, new_data )) if i == 0: self.out_arr = array print "Array shape:", self.out_arr.shape else: self.out_arr = np.vstack( (self.out_arr, array) ) print "Array shape:", self.out_arr.shape date = time.localtime() outfile = self.model.savepath + self.model.filename outfile += str(date[0]) + '_' + str(date[1]) + '_' + str(date[2]) + '_' outfile += str(date[3]) + '-' + str(date[4]) + '_run_number_' + str(self.run_number) np.savez(outfile, data=self.out_arr, time_stamps=self.model._tdata) # time_outfile = outfile + '_t' # np.savez(time_outfile, self.model._tdata) print "Saved ", outfile # Plot the data collected this last run self.plot_last_data() # clean up self.reset_variables() def reset_variables(self): self.out_arr = None self.ttl_received = False self.run_number += 1 self.model.recording = False self.trialEnded = True self.plot.delplot('old') def plot_last_data(self): import pylab as pl if self.out_arr.shape[1] == 4: pl.figure() pl.subplot(411) pl.plot(self.out_arr[:,0]) pl.subplot(412) pl.plot(self.out_arr[:,1]) pl.subplot(413) pl.plot(self.out_arr[:,2]) pl.subplot(414) pl.plot(self.out_arr[:,3]) pl.show()