def traits_view(self): v = View(UItem('container', editor=ComponentEditor()), resizable=True, handler=self.handler_klass) return v
Item( name='thresh', label='Pj Thresh.', tooltip= "Threshold for identifying periodic jitter spectral elements. (sigma)", ), label='Analysis Parameters', show_border=True, ), ), label='Config.', id='config', ), Group(Item( 'plots_dfe', editor=ComponentEditor(), show_label=False, ), label='DFE', id='plots_dfe'), VGroup( HGroup( VGroup( HGroup( Item( name='pretap_tune_enable', label='Enable', tooltip="Enable this tap.", ), Item( name='pretap_tune',
class PlotViewer(HasTraits): plot = Instance(Plot) traits_view = View(Item('plot', editor=ComponentEditor()))
class CameraWindow(HasTraits): """ CameraWindow class contains the relevant information and functions for a single camera window: image, zoom, pan important members: _plot_data - contains image data to display (used by update_image) _plot - instance of Plot class to use with _plot_data _click_tool - instance of Clicker tool for the single camera window, to handle mouse processing """ _plot_data = Instance(ArrayPlotData) _plot = Instance(Plot) _click_tool = Instance(Clicker) rclicked = Int(0) cam_color = '' name = Str view = View(Item(name='_plot', editor=ComponentEditor(), show_label=False)) # view = View( Item(name='_plot',show_label=False) ) def __init__(self, color): """ Initialization of plot system """ padd = 25 self._plot_data = ArrayPlotData() self._plot = Plot(self._plot_data, default_origin="top left") self._plot.padding_left = padd self._plot.padding_right = padd self._plot.padding_top = padd self._plot.padding_bottom = padd self.right_p_x0,self.right_p_y0,self.right_p_x1,self.right_p_y1,self._quiverplots=[],[],[],[],[] self.cam_color = color def attach_tools(self): """ attach_tools(self) contains the relevant tools: clicker, pan, zoom """ self._click_tool = Clicker(self._img_plot) self._click_tool.on_trait_change( self.left_clicked_event, 'left_changed') #set processing events for Clicker self._click_tool.on_trait_change(self.right_clicked_event, 'right_changed') self._img_plot.tools.append(self._click_tool) pan = PanTool(self._plot, drag_button='middle') zoom_tool = ZoomTool(self._plot, tool_mode="box", always_on=False) # zoom_tool = BetterZoom(component=self._plot, tool_mode="box", always_on=False) zoom_tool.max_zoom_out_factor = 1.0 # Disable "bird view" zoom out self._img_plot.overlays.append(zoom_tool) self._img_plot.tools.append(pan) def left_clicked_event( self ): #TODO: why do we need the clicker_tool if we can handle mouse clicks here? """ left_clicked_event - processes left click mouse avents and displays coordinate and grey value information on the screen """ print("x = %d, y= %d, grey= %d " % (self._click_tool.x, self._click_tool.y, self._click_tool.data_value)) #need to priny gray value def right_clicked_event(self): self.rclicked = 1 #flag that is tracked by main_gui, for right_click_process function of main_gui #self._click_tool.y,self.name]) #self.drawcross("coord_x","coord_y",self._click_tool.x,self._click_tool.y,"red",5) #print ("right clicked, "+self.name) #need to print cross and manage other camera's crosses def update_image(self, image, is_float=False): """ update_image - displays/updates image in the curren camera window parameters: image - image data is_float - if true, displays an image as float array, else displays as byte array (B&W or gray) example usage: update_image(image,is_float=False) """ print('image shape = ', image.shape, 'is_float =', is_float) if image.ndim > 2: image = img_as_ubyte(rgb2gray(image)) is_float = False if is_float: self._plot_data.set_data('imagedata', image.astype(np.float)) else: self._plot_data.set_data('imagedata', image.astype(np.byte)) if not hasattr( self, '_img_plot'): #make a new plot if there is nothing to update self._img_plot = Instance(ImagePlot) self._img_plot = self._plot.img_plot('imagedata', colormap=gray)[0] self.attach_tools() # self._plot.request_redraw() def drawcross(self, str_x, str_y, x, y, color1, mrk_size, marker1="plus"): """ drawcross draws crosses at a given location (x,y) using color and marker in the current camera window parameters: str_x - label for x coordinates str_y - label for y coordinates x - array of x coordinates y - array of y coordinates mrk_size - marker size makrer1 - type of marker, e.g "plus","circle" example usage: drawcross("coord_x","coord_y",[100,200,300],[100,200,300],2) draws plus markers of size 2 at points (100,100),(200,200),(200,300) """ self._plot_data.set_data(str_x, x) self._plot_data.set_data(str_y, y) self._plot.plot((str_x, str_y), type="scatter", color=color1, marker=marker1, marker_size=mrk_size) #self._plot.request_redraw() def drawquiver(self, x1c, y1c, x2c, y2c, color, linewidth=1.0): """ drawquiver draws multiple lines at once on the screen x1,y1->x2,y2 in the current camera window parameters: x1c - array of x1 coordinates y1c - array of y1 coordinates x2c - array of x2 coordinates y2c - array of y2 coordinates color - color of the line linewidth - linewidth of the line example usage: drawquiver ([100,200],[100,100],[400,400],[300,200],'red',linewidth=2.0) draws 2 red lines with thickness = 2 : 100,100->400,300 and 200,100->400,200 """ x1, y1, x2, y2 = self.remove_short_lines(x1c, y1c, x2c, y2c) if len(x1) > 0: xs = ArrayDataSource(x1) ys = ArrayDataSource(y1) quiverplot=QuiverPlot(index=xs,value=ys,\ index_mapper=LinearMapper(range=self._plot.index_mapper.range),\ value_mapper=LinearMapper(range=self._plot.value_mapper.range),\ origin = self._plot.origin,arrow_size=0,\ line_color=color,line_width=linewidth,ep_index=np.array(x2),ep_value=np.array(y2) ) self._plot.add(quiverplot) self._quiverplots.append( quiverplot ) #we need this to track how many quiverplots are in the current plot # import pdb; pdb.set_trace() def remove_short_lines(self, x1, y1, x2, y2): """ removes short lines from the array of lines parameters: x1,y1,x2,y2 - start and end coordinates of the lines returns: x1f,y1f,x2f,y2f - start and end coordinates of the lines, with short lines removed example usage: x1,y1,x2,y2=remove_short_lines([100,200,300],[100,200,300],[100,200,300],[102,210,320]) 3 input lines, 1 short line will be removed (100,100->100,102) returned coordinates: x1=[200,300]; y1=[200,300]; x2=[200,300]; y2=[210,320] """ dx, dy = 2, 2 #minimum allowable dx,dy x1f, y1f, x2f, y2f = [], [], [], [] for i in range(len(x1)): if abs(x1[i] - x2[i]) > dx or abs(y1[i] - y2[i]) > dy: x1f.append(x1[i]) y1f.append(y1[i]) x2f.append(x2[i]) y2f.append(y2[i]) return x1f, y1f, x2f, y2f def drawline(self, str_x, str_y, x1, y1, x2, y2, color1): """ drawline draws 1 line on the screen by using lineplot x1,y1->x2,y2 parameters: str_x - label of x coordinate str_y - label of y coordinate x1,y1,x2,y2 - start and end coordinates of the line color1 - color of the line example usage: drawline("x_coord","y_coord",100,100,200,200,red) draws a red line 100,100->200,200 """ self._plot_data.set_data(str_x, [x1, x2]) self._plot_data.set_data(str_y, [y1, y2]) self._plot.plot((str_x, str_y), type="line", color=color1)
class ContainerExample(HasTraits): plot = Instance(HPlotContainer) display_button = Button() display_button1 = Button() prev = Button() next = Button() unzoom = Button() traits_view = View( Group(Item('display_button', show_label=False), Item('display_button1', show_label=False), Item('prev', show_label=False), Item('next', show_label=False), Item('unzoom', show_label=False), orientation="horizontal"), Item('plot', editor=ComponentEditor(), show_label=False), # put the info box that lists the mouse location tuple kls karl width=1000, height=600, resizable=True, title="Chaco Plot", # How do I activate these? buttons=["do_nothing","do_nothing_1"] ) def __init__(self): super(ContainerExample, self).__init__() filenames = [] for parameter in sys.argv[1:]: print "processing parameter", parameter if parameter.find("=") == -1: print "no = in parameter", parameter, "must be a file name" filenames.append(parameter) if len(filenames) < 1: print "just to help me test, if there are no files in the list, " print "I will append the file foldplot1.rsf" filenames.append('foldplot1.rsf') self.seis_data_0 = SeisData(filenames[0]) self.cmap = jet self.displayParameters = DisplayParameters() self.slice_y = self.displayParameters.slice_y print "self.slice_y=", self.slice_y self.arrayPlotData = ArrayPlotData() self._update_images() x_extents = (self.seis_data_0.axis_start[1], self.seis_data_0.axis_end[1]) y_extents = (self.seis_data_0.axis_start[2], self.seis_data_0.axis_end[2]) bottomplot = Plot(self.arrayPlotData, origin="top left") self.bottomplot = bottomplot imgplot = bottomplot.img_plot("xz", xbounds=x_extents, ybounds=y_extents, colormap=self.cmap)[0] self.bottom = imgplot plotright = Plot(self.arrayPlotData, origin="top left", range2d=bottomplot.range2d) imgplotright = plotright.img_plot("xz", xbounds=x_extents, ybounds=y_extents, colormap=self.cmap)[0] self.right = imgplotright container = HPlotContainer(fill_padding=True, bgcolor="white", use_backbuffer=True) container.add(bottomplot) container.add(plotright) self.plot = container self.displayParameters = DisplayParameters() self.slice_y = self.displayParameters.slice_y imgplot.tools.append(CustomTool(imgplot)) imgplot.tools.append(PanTool(imgplot, constrain_key="shift")) imgplot.overlays.append( ZoomTool(component=imgplot, tool_mode="box", always_on=False)) imgplotright.tools.append(PanTool(imgplotright, constrain_key="shift")) imgplotright.overlays.append( ZoomTool(component=self.right, tool_mode="box", always_on=False)) def _update_images(self): if self.displayParameters.gain != 0: rgain = 1. / self.displayParameters.gain else: rgain = 1 print "rgain=", rgain range = DataRange1D(low=self.seis_data_0.minval * rgain, high=self.seis_data_0.maxval * rgain) self.colormap = self.cmap(range) slice = transpose(self.seis_data_0.vals[self.slice_y, :, :]) self.slice = slice colorslice = (self.colormap.map_screen(slice) * 255).astype(uint8) # Transposed required because img_plot() expects data in row-major order # self.arrayPlotData.set_data("xz", colorslicexz) self.arrayPlotData.set_data("xz", colorslice) def _marker_size_changed(self): self.scatter.marker_size = self.marker_size def _color_changed(self): self.scatter.marker_size = self.marker_size def _display_button_fired(self): print "Display button pushed" self.displayParameters.edit_traits() self._update_images() def _prev_fired(self): print "prev button pushed" slice_y = self.slice_y - self.displayParameters.slice_inc if (slice_y < 0): slice_y = self.seis_data_0.vals.shape[0] - 1 print "after decrement slice_y=", slice_y self.slice_y = slice_y self._update_images() def _next_fired(self): print "next button pushed" slice_y = self.slice_y + self.displayParameters.slice_inc print "shape=", self.seis_data_0.vals.shape if (slice_y >= self.seis_data_0.vals.shape[0]): slice_y = 0 print "after increment slice_y=", slice_y self.slice_y = slice_y self._update_images() def _unzoom_fired(self): print "unzoom button pushed" print "self.bottomplot.range2d=", self.bottomplot.range2d print "xmin/xmax=", \ self.bottomplot.range2d.x_range.low, \ self.bottomplot.range2d.x_range.high print "ymin/ymax=", \ self.bottomplot.range2d.y_range.low, \ self.bottomplot.range2d.y_range.high self.bottomplot.range2d.x_range.low = self.seis_data_0.axis_start[1] self.bottomplot.range2d.x_range.high = self.seis_data_0.axis_end[1] self.bottomplot.range2d.y_range.low = self.seis_data_0.axis_start[2] self.bottomplot.range2d.y_range.high = self.seis_data_0.axis_end[2]
class PlotApp(HasTraits): plotdata = Instance(ArrayPlotData) numpoints = Int(300) symbols = List() sym1 = Enum(values="symbols") sym2 = Enum(values="symbols") returns_plot = Instance(Plot) times_ds = Any() # arraydatasource for the time axis data corr_plot = Instance(Plot) corr_renderer = Any() traits_view = View( HSplit( Item( 'returns_plot', editor=ComponentEditor(), show_label=False), VGroup( VGroup( Item( 'sym1', width=-225), Item( 'sym2', width=-225), ), Item( 'corr_plot', editor=ComponentEditor(), show_label=False, width=-275), ), ), width=1024, height=500, resizable=True, title="Correlations of returns") def __init__(self, *symbols, **kwtraits): super(PlotApp, self).__init__(symbols=list(symbols), **kwtraits) self._create_data(*symbols) self._create_returns_plot() self._create_corr_plot() if len(self.symbols) > 1: self.sym2 = self.symbols[1] return def _create_returns_plot(self): plot = Plot(self.plotdata) plot.legend.visible = True #FIXME: The legend move tool doesn't seem to quite work right now #plot.legend.tools.append(LegendTool(plot.legend)) plot.x_axis = None x_axis = PlotAxis( plot, orientation="bottom", tick_generator=ScalesTickGenerator(scale=CalendarScaleSystem())) plot.overlays.append(x_axis) plot.x_grid.tick_generator = x_axis.tick_generator for i, name in enumerate(self.plotdata.list_data()): if name == "times": continue renderer = plot.plot( ("times", name), type="line", name=name, color=tuple(COLOR_PALETTE[i]))[0] # Tricky: need to set auto_handle_event on the RangeSelection # so that it passes left-clicks to the PanTool # FIXME: The range selection is still getting the initial left down renderer.tools.append( RangeSelection( renderer, left_button_selects=False, auto_handle_event=False)) plot.tools.append( PanTool( plot, drag_button="left", constrain=True, constrain_direction="x")) plot.overlays.append( ZoomTool( plot, tool_mode="range", max_zoom_out=1.0)) # Attach the range selection to the last renderer; any one will do self._range_selection_overlay = RangeSelectionOverlay( renderer, metadata_name="selections") renderer.overlays.append(self._range_selection_overlay) # Grab a reference to the Time axis datasource and add a listener to its # selections metadata self.times_ds = renderer.index self.times_ds.on_trait_change(self._selections_changed, 'metadata_changed') self.returns_plot = plot def _create_corr_plot(self): plot = Plot(self.plotdata, padding=0) plot.padding_left = 25 plot.padding_bottom = 25 plot.tools.append(PanTool(plot)) plot.overlays.append(ZoomTool(plot)) self.corr_plot = plot def _create_data(self, *names): numpoints = self.numpoints plotdata = ArrayPlotData(times=create_dates(numpoints)) for name in names: plotdata.set_data( name, cumprod(random.lognormal( 0.0, 0.04, size=numpoints))) self.plotdata = plotdata def _selections_changed(self, event): if self.corr_renderer is None: return if not isinstance(event, dict) or "selections" not in event: return corr_index = self.corr_renderer.index selections = event["selections"] if selections is None: corr_index.metadata.pop("selections", None) return else: low, high = selections data = self.times_ds.get_data() low_ndx = data.searchsorted(low) high_ndx = data.searchsorted(high) corr_index.metadata["selections"] = arange( low_ndx, high_ndx + 1, 1, dtype=int) self.corr_plot.request_redraw() @on_trait_change("sym1,sym2") def _update_corr_symbols(self): plot = self.corr_plot if self.corr_renderer is not None: # Remove the old one plot.remove(self.corr_renderer) self.corr_renderer = None self.corr_renderer = plot.plot( (self.sym1, self.sym2), type="scatter", color="blue")[0] self.corr_renderer.overlays.append( ScatterInspectorOverlay( self.corr_renderer, selection_color="lightgreen")) plot.request_redraw()
def create_editor(self): return ComponentEditor()
Item(name='sum_bw', label='BW (GHz)', tooltip="summing node bandwidth", enabled_when='sum_ideal == False'), ), label='DFE Parameters', show_border=True, enabled_when='use_dfe == True', # enabled_when='rx_use_ami == False or rx_use_ami == True and rx_use_getwave == False', ), ), # spring, label = 'Config.', id = 'config', ), Group( Item('console_log', show_label=False, style='custom'), label = 'Console', id = 'console' ), Group( Item('plots_dfe', editor=ComponentEditor(), show_label=False,), label = 'DFE', id = 'plots_dfe' ), # "EQ Tune" tab. VGroup( HGroup( Group( Item( name='tx_tap_tuners', editor=TableEditor(columns=[ObjectColumn(name='name', editable=False), ObjectColumn(name='enabled'), ObjectColumn(name='min_val'), ObjectColumn(name='max_val'), ObjectColumn(name='value', format='%+05.3f'), ], configurable=False, reorderable=False,
class ThetaTensorPlot(PyannoPlotContainer): # reference to the theta tensor for one annotator theta = Array # reference to an array of samples for theta for one annotator theta_samples = Any # index of the annotator annotator_idx = Int # chaco plot of the tensor theta_plot = Any def _label_name(self, k): """Return a name for the data with index `k`.""" nclasses = self.theta.shape[0] ndigits = int(np.ceil(np.log10(nclasses))) format_str = 'theta[{{}},{{:{}d}},:]'.format(ndigits) return format_str.format(self.annotator_idx, k) def _plot_samples(self, plot, plot_data): nclasses = self.theta.shape[0] nsamples = self.theta_samples.shape[0] for k in range(nclasses): samples = np.sort(self.theta_samples[:, k, :], axis=0) perc5 = samples[int(nsamples * 0.05), :] perc95 = samples[int(nsamples * 0.95), :] avg = samples.mean(0) # build polygon index_name = self._label_name(k) + '_confint_index' value_name = self._label_name(k) + '_confint_value' index_coord = [] value_coord = [] # bottom part for i in range(nclasses): index_coord.append(i) value_coord.append(perc5[i]) # top part for i in range(nclasses - 1, -1, -1): index_coord.append(i) value_coord.append(perc95[i]) plot_data.set_data(index_name, np.array(index_coord, dtype=float)) plot_data.set_data(value_name, np.array(value_coord, dtype=float)) # make color lighter and more transparent color = get_class_color(k) for i in range(3): color[i] = min(1.0, sigmoid(color[i] * 5.)) color[-1] = 0.3 plot.plot((index_name, value_name), type='polygon', face_color=color, edge_color='black', edge_width=0.5) # add average avg_name = self._label_name(k) + '_avg_value' plot_data.set_data(avg_name, avg) plot.plot(('classes', avg_name), color=get_class_color(k), line_style='dash') def _plot_theta_values(self, plot, plot_data): theta = self.theta nclasses = theta.shape[0] data_names = ['classes'] for k in range(nclasses): name = self._label_name(k) plot_data.set_data(name, theta[k, :]) data_names.append(name) plots = {} for k in range(nclasses): name = self._label_name(k) line_plot = plot.plot(['classes', name], line_width=2., color=get_class_color(k), name=name) plots[name] = line_plot return plots def _theta_plot_default(self): theta = self.theta nclasses = theta.shape[0] # create a plot data object and give it this data plot_data = ArrayPlotData() plot_data.set_data('classes', range(nclasses)) # create the plot plot = Plot(plot_data) # --- plot theta samples if self.theta_samples is not None: self._plot_samples(plot, plot_data) # --- plot values of theta plots = self._plot_theta_values(plot, plot_data) # --- adjust plot appearance plot.aspect_ratio = 1.6 if is_display_small() else 1.7 # adjust axis bounds y_high = theta.max() if self.theta_samples is not None: y_high = max(y_high, self.theta_samples.max()) plot.range2d = DataRange2D(low=(-0.2, 0.0), high=(nclasses - 1 + 0.2, y_high * 1.1)) # create new horizontal axis label_axis = self._create_increment_one_axis(plot, 0., nclasses, 'bottom') label_axis.title = 'True classes' self._add_index_axis(plot, label_axis) # label vertical axis plot.value_axis.title = 'Probability' # add legend legend = Legend(component=plot, plots=plots, align="ur", border_padding=10) legend.tools.append(LegendTool(legend, drag_button="left")) legend.padding_right = -100 plot.overlays.append(legend) container = VPlotContainer(width=plot.width + 100, halign='left') plot.padding_bottom = 50 plot.padding_top = 10 plot.padding_left = 0 container.add(plot) container.bgcolor = 0xFFFFFF self.decorate_plot(container, theta) return container #### View definition ##################################################### resizable_plot_item = Item('theta_plot', editor=ComponentEditor(), resizable=True, show_label=False, height=-250, width=-500) traits_plot_item = Instance(Item) def _traits_plot_item_default(self): height = -200 if is_display_small() else -250 return Item( 'theta_plot', editor=ComponentEditor(), resizable=False, show_label=False, height=height, )
class ThetaDistrPlot(PyannoPlotContainer): """Defines a view of the annotator accuracy parameters, theta. The view consists in a Chaco plot that displays the theta parameter for each annotator, and samples from the posterior distribution over theta as a discretized distribution over theta. """ # reference to the theta tensor for one annotator theta = Array # reference to an array of samples for theta for one annotator theta_samples = Any # chaco plot of the tensor theta_plot = Any def _theta_name(self, k): nannotators = self.theta.shape[0] ndigits = int(np.ceil(np.log10(nannotators))) format_str = 'theta[{{:{}d}}]'.format(ndigits) return format_str.format(k) def _theta_plot_default(self): theta = self.theta nannotators = theta.shape[0] samples = self.theta_samples # plot data object plot_data = ArrayPlotData() # create the plot plot = Plot(plot_data) # --- plot theta as vertical dashed lines # add vertical lines extremes plot_data.set_data('line_extr', [0., 1.]) for k in range(nannotators): name = self._theta_name(k) plot_data.set_data(name, [theta[k], theta[k]]) plots = {} for k in range(nannotators): name = self._theta_name(k) line_plot = plot.plot((name, 'line_extr'), line_width=2., color=get_annotator_color(k), line_style='dash', name=name) plots[name] = line_plot # --- plot samples as distributions if samples is not None: bins = np.linspace(0., 1., 100) max_hist = 0. for k in range(nannotators): name = self._theta_name(k) + '_distr_' hist, x = np.histogram(samples[:, k], bins=bins) hist = hist / float(hist.sum()) max_hist = max(max_hist, hist.max()) # make "bars" out of histogram values y = np.concatenate(([0], np.repeat(hist, 2), [0])) plot_data.set_data(name + 'x', np.repeat(x, 2)) plot_data.set_data(name + 'y', y) for k in range(nannotators): name = self._theta_name(k) + '_distr_' plot.plot((name + 'x', name + 'y'), line_width=2., color=get_annotator_color(k)) # --- adjust plot appearance plot.aspect_ratio = 1.6 if is_display_small() else 1.7 plot.padding = [20, 0, 10, 40] # adjust axis bounds x_low, x_high = theta.min(), theta.max() y_low, y_high = 0., 1. if samples is not None: x_high = max(x_high, samples.max()) x_low = min(x_low, samples.min()) y_high = max_hist plot.range2d = DataRange2D(low=(max(x_low - 0.05, 0.), y_low), high=(min(x_high * 1.1, 1.), min(y_high * 1.1, 1.))) # label axes plot.value_axis.title = 'Probability' plot.index_axis.title = 'Theta' # add legend legend = Legend(component=plot, plots=plots, align="ul", padding=5) legend.tools.append(LegendTool(legend, drag_button="left")) plot.overlays.append(legend) container = VPlotContainer() container.add(plot) container.bgcolor = 0xFFFFFF self.decorate_plot(container, theta) self._set_title(plot) return container #### View definition ##################################################### resizable_plot_item = Item('theta_plot', editor=ComponentEditor(), resizable=True, show_label=False, width=600) traits_plot_item = Instance(Item) def _traits_plot_item_default(self): height = -220 if is_display_small() else -280 return Item( 'theta_plot', editor=ComponentEditor(), resizable=False, show_label=False, height=height, )
class ThetaScatterPlot(ModelView, PyannoPlotContainer): """Defines a view of the annotator accuracy parameters, theta. The view consists in a Chaco plot that displays the theta parameter for each annotator, and samples from the posterior distribution over theta with a combination of a scatter plot and a candle plot. """ #### Traits definition #################################################### theta_samples_valid = Bool(False) theta_samples = Array(dtype=float, shape=(None, None)) # return value for "Copy" action on plot data = DictStrAny def _data_default(self): return {'theta': self.model.theta, 'theta_samples': None} @on_trait_change('redraw,theta_samples,theta_samples_valid') def _update_data(self): if self.theta_samples_valid: theta_samples = self.theta_samples else: theta_samples = None self.data['theta'] = self.model.theta self.data['theta_samples'] = theta_samples #### plot-related traits title = Str('Accuracy (theta)') theta_plot_data = Instance(ArrayPlotData) theta_plot = Any redraw = Event ### Plot definition ####################################################### def _compute_range2d(self): low = min(0.6, self.model.theta.min() - 0.05) if self.theta_samples_valid: low = min(low, self.theta_samples.min() - 0.05) range2d = DataRange2D(low=(0., low), high=(self.model.theta.shape[0] + 1, 1.)) return range2d @on_trait_change('redraw', post_init=True) def _update_range2d(self): self.theta_plot.range2d = self._compute_range2d() def _theta_plot_default(self): """Create plot of theta parameters.""" # We plot both the thetas and the samples from the posterior; if the # latter are not defined, the corresponding ArrayPlotData names # should be set to an empty list, so that they are not displayed theta = self.model.theta theta_len = theta.shape[0] # create the plot data if not self.theta_plot_data: self.theta_plot_data = ArrayPlotData() self._update_plot_data() # create the plot theta_plot = Plot(self.theta_plot_data) for idx in range(theta_len): # candle plot summarizing samples over the posterior theta_plot.candle_plot( (_w_idx('index', idx), _w_idx('min', idx), _w_idx( 'barmin', idx), _w_idx('avg', idx), _w_idx( 'barmax', idx), _w_idx('max', idx)), color=get_annotator_color(idx), bar_line_color="black", stem_color="blue", center_color="red", center_width=2) # plot of raw samples theta_plot.plot((_w_idx('ysamples', idx), _w_idx('xsamples', idx)), type='scatter', color='black', marker='dot', line_width=0.5, marker_size=1) # plot current parameters theta_plot.plot((_w_idx('y', idx), _w_idx('x', idx)), type='scatter', color=get_annotator_color(idx), marker='plus', marker_size=8, line_width=2) # adjust axis bounds theta_plot.range2d = self._compute_range2d() # remove horizontal grid and axis theta_plot.underlays = [theta_plot.x_grid, theta_plot.y_axis] # create new horizontal axis label_list = [str(i) for i in range(theta_len)] label_axis = LabelAxis(theta_plot, orientation='bottom', positions=range(1, theta_len + 1), labels=label_list, label_rotation=0) # use a FixedScale tick generator with a resolution of 1 label_axis.tick_generator = ScalesTickGenerator(scale=FixedScale(1.)) theta_plot.index_axis = label_axis theta_plot.underlays.append(label_axis) theta_plot.padding = 25 theta_plot.padding_left = 40 theta_plot.aspect_ratio = 1.0 container = VPlotContainer() container.add(theta_plot) container.bgcolor = 0xFFFFFF self.decorate_plot(container, theta) self._set_title(theta_plot) return container ### Handle plot data ###################################################### def _samples_names_and_values(self, idx): """Return a list of names and values for the samples PlotData.""" # In the following code, we rely on lazy evaluation of the # X if CONDITION else Y statements to return a default value if the # theta samples are not currently defined, or the real value if they # are. invalid = not self.theta_samples_valid samples = [] if invalid else np.sort(self.theta_samples[:, idx]) nsamples = None if invalid else samples.shape[0] perc5 = None if invalid else samples[int(nsamples * 0.05)] perc95 = None if invalid else samples[int(nsamples * 0.95)] data_dict = { 'xsamples': [] if invalid else samples, 'ysamples': [] if invalid else (np.random.random(size=(nsamples, )) * 0.1 - 0.05 + idx + 1.2), 'min': [] if invalid else [perc5], 'max': [] if invalid else [perc95], 'barmin': [] if invalid else [samples.mean() - samples.std()], 'barmax': [] if invalid else [samples.mean() + samples.std()], 'avg': [] if invalid else [samples.mean()], 'index': [] if invalid else [idx + 0.8] } name_value = [(_w_idx(name, idx), value) for name, value in data_dict.items()] return name_value @on_trait_change('theta_plot_data,theta_samples_valid,redraw') def _update_plot_data(self): """Updates PlotData on changes.""" theta = self.model.theta plot_data = self.theta_plot_data if plot_data is not None: for idx, th in enumerate(theta): plot_data.set_data('x%d' % idx, [th]) plot_data.set_data('y%d' % idx, [idx + 1.2]) for name_value in self._samples_names_and_values(idx): name, value = name_value plot_data.set_data(name, value) #### View definition ##################################################### resizable_plot_item = Item('theta_plot', editor=ComponentEditor(), resizable=True, show_label=False, width=600, height=400) traits_plot_item = Instance(Item) def _traits_plot_item_default(self): height = -220 if is_display_small() else -280 return Item('theta_plot', editor=ComponentEditor(), resizable=False, show_label=False, height=height)
class Bullseye(HasTraits): plots = Instance(GridPlotContainer) abplots = Instance(VPlotContainer) screen = Instance(Plot) horiz = Instance(Plot) vert = Instance(Plot) asum = Instance(Plot) bsum = Instance(Plot) process = Instance(Process) colormap = Enum("gray", "jet", "hot", "prism") invert = Bool(True) label = None gridm = None grid = None traits_view = View(HGroup(VGroup( HGroup( VGroup( Item("object.process.x", label="Centroid x", format_str=u"%.4g µm", tooltip="horizontal beam position relative to chip " "center"), Item("object.process.a", label="Major 4sig", format_str=u"%.4g µm", tooltip="major axis beam width 4 sigma ~ 1/e^2 width"), Item("object.process.t", label="Rotation", format_str=u"%.4g°", tooltip="angle between horizontal an major axis"), #Item("object.process.black", label="Black", # format_str=u"%.4g", # tooltip="background black level"), ), VGroup( Item("object.process.y", label="Centroid y", format_str=u"%.4g µm", tooltip="vertical beam position relative to chip " "center"), Item("object.process.b", label="Minor 4sig", format_str=u"%.4g µm", tooltip="major axis beam width 4 sigma ~ 1/e^2 width"), #Item("object.process.d", label="Mean width", # format_str=u"%.4g µm", # tooltip="mean beam width 4 sigma ~ 1/e^2 width"), #Item("object.process.e", label="Ellipticity", # format_str=u"%.4g", # tooltip="ellipticity minor-to-major width ratio"), #Item("object.process.peak", label="Peak", # format_str=u"%.4g", # tooltip="peak pixel level"), Item("object.process.include_radius", label="Include radius", format_str=u"%.4g µm", tooltip="energy inclusion radius according to ignore " "level, used to crop before taking moments"), ), style="readonly", ), VGroup( Item("object.process.capture.shutter", tooltip="exposure time per frame in seconds"), Item("object.process.capture.gain", tooltip="analog camera gain in dB"), Item("object.process.capture.framerate", tooltip="frames per second to attempt, may be limited by " "shutter time and processing speed"), Item("object.process.capture.average", tooltip="number of subsequent images to boxcar average"), Item("object.process.background", tooltip="background intensity percentile to subtract " "from image"), Item("object.process.ignore", tooltip="fraction of total intensity to ignore for " "cropping, determines include radius"), ), HGroup( Item("object.process.active", tooltip="capture and processing running"), Item("object.process.capture.auto_shutter", tooltip="adjust the shutter time to " "yield acceptably exposed frames with peak values " "between .25 and .75"), Item("object.process.track", tooltip="adjust the region of interest to track the " "beam center, the size is not adjusted"), Item("object.process.capture.dark", tooltip="capture a dark image and subtract it from " "subsequent images, reset if gain or shutter change"), ), HGroup( UItem("colormap", tooltip="image colormap"), Item("invert", tooltip="invert the colormap"), ), UItem("abplots", editor=ComponentEditor(), width=-200, height=-300, resizable=False, tooltip="line sums (red), moments (blue) and " "2-sigma markers (green) along the major and minor axes", ), ), UItem("plots", editor=ComponentEditor(), width=800, tooltip="top right: beam image with 2-sigma and 6-sigma " "radius ellipses and axis markers (green). top left and bottom " "right: vertial and horizontal line sums (red), moments " "(blue) and 2-sigma markers (green). bottom left: beam data " "from moments"), layout="split", ), resizable=True, title=u"Bullseye ― Beam Profiler", width=1000) def __init__(self, **k): super(Bullseye, self).__init__(**k) self.data = ArrayPlotData() self.process.initialize() self.setup_plots() self.update_data() self.populate_plots() self.on_trait_change(self.update_data, "process.new_data", dispatch="fast_ui") def setup_plots(self): self.screen = Plot(self.data, resizable="hv", padding=0, bgcolor="lightgray", border_visible=False) self.screen.index_grid.visible = False self.screen.value_grid.visible = False px = self.process.capture.pixelsize w, h = self.process.capture.width, self.process.capture.height # value_range last, see set_range() self.screen.index_range.low_setting = -w/2*px self.screen.index_range.high_setting = w/2*px self.screen.value_range.low_setting = -h/2*px self.screen.value_range.high_setting = h/2*px self.horiz = Plot(self.data, resizable="h", padding=0, height=100, bgcolor="lightgray", border_visible=False) self.horiz.value_mapper.range.low_setting = \ -.1*self.process.capture.maxval self.horiz.index_range = self.screen.index_range self.vert = Plot(self.data, orientation="v", resizable="v", padding=0, width=100, bgcolor="lightgray", border_visible=False) for p in self.horiz, self.vert: p.index_axis.visible = False p.value_axis.visible = False p.index_grid.visible = True p.value_grid.visible = False self.vert.value_mapper.range.low_setting = \ -.1*self.process.capture.maxval self.vert.index_range = self.screen.value_range #self.vert.value_range = self.horiz.value_range self.mini = Plot(self.data, width=100, height=100, resizable="", padding=0, bgcolor="lightgray", border_visible=False) self.mini.index_axis.visible = False self.mini.value_axis.visible = False self.label = PlotLabel(component=self.mini, overlay_position="inside left", font="modern 10", text=self.process.text) self.mini.overlays.append(self.label) self.plots = GridPlotContainer(shape=(2, 2), padding=0, spacing=(5, 5), use_backbuffer=True, bgcolor="lightgray") self.plots.component_grid = [[self.vert, self.screen], [self.mini, self.horiz ]] self.screen.overlays.append(ZoomTool(self.screen, x_max_zoom_factor=1e2, y_max_zoom_factor=1e2, x_min_zoom_factor=0.5, y_min_zoom_factor=0.5, zoom_factor=1.2)) self.screen.tools.append(PanTool(self.screen)) self.plots.tools.append(SaveTool(self.plots, filename="bullseye.pdf")) self.asum = Plot(self.data, padding=0, height=100, bgcolor="lightgray", title="major axis", border_visible=False) self.bsum = Plot(self.data, padding=0, height=100, bgcolor="lightgray", title="minor axis", border_visible=False) for p in self.asum, self.bsum: p.value_axis.visible = False p.value_grid.visible = False p.title_font = "modern 10" p.title_position = "left" p.title_angle = 90 # lock scales #self.bsum.value_range = self.asum.value_range #self.bsum.index_range = self.asum.index_range self.abplots = VPlotContainer(padding=20, spacing=20, use_backbuffer=True,bgcolor="lightgray", fill_padding=True) self.abplots.add(self.bsum, self.asum) def populate_plots(self): self.screenplot = self.screen.img_plot("img", xbounds="xbounds", ybounds="ybounds", interpolation="nearest", colormap=color_map_name_dict[self.colormap], )[0] self.set_invert() self.grid = self.screenplot.index self.gridm = self.screenplot.index_mapper t = ImageInspectorTool(self.screenplot) self.screen.tools.append(t) self.screenplot.overlays.append(ImageInspectorOverlay( component=self.screenplot, image_inspector=t, border_size=0, bgcolor="transparent", align="ur", tooltip_mode=False, font="modern 10")) self.horiz.plot(("x", "imx"), type="line", color="red") self.vert.plot(("y", "imy"), type="line", color="red") self.horiz.plot(("x", "gx"), type="line", color="blue") self.vert.plot(("y", "gy"), type="line", color="blue") self.asum.plot(("a", "ima"), type="line", color="red") self.bsum.plot(("b", "imb"), type="line", color="red") self.asum.plot(("a", "ga"), type="line", color="blue") self.bsum.plot(("b", "gb"), type="line", color="blue") for p in [("ell1_x", "ell1_y"), ("ell3_x", "ell3_y"), ("a_x", "a_y"), ("b_x", "b_y")]: self.screen.plot(p, type="line", color="green", alpha=.5) for r, s in [("x", self.horiz), ("y", self.vert), ("a", self.asum), ("b", self.bsum)]: for p in "0 p m".split(): q = ("%s%s_mark" % (r, p), "%s_bar" % r) s.plot(q, type="line", color="green") def __del__(self): self.close() def close(self): self.process.active = False @on_trait_change("colormap") def set_colormap(self): p = self.screenplot m = color_map_name_dict[self.colormap] p.color_mapper = m(p.value_range) self.set_invert() p.request_redraw() @on_trait_change("invert") def set_invert(self): p = self.screenplot if self.invert: a, b = self.process.capture.maxval, 0 else: a, b = 0, self.process.capture.maxval p.color_mapper.range.low_setting = a p.color_mapper.range.high_setting = b # TODO: bad layout for one frame at activation, track # value_range seems to be updated after index_range, take this @on_trait_change("screen.value_range.updated") def set_range(self): if self.gridm is not None: #enforce data/screen aspect ratio 1 sl, sr, sb, st = self.gridm.screen_bounds dl, db = self.gridm.range.low dr, dt = self.gridm.range.high #dsdx = float(sr-sl)/(dr-dl) dsdy = float(st-sb)/(dt-db) #dt_new = db+(st-sb)/dsdx if dsdy: dr_new = dl+(sr-sl)/dsdy self.gridm.range.x_range.high_setting = dr_new l, r = self.screen.index_range.low, self.screen.index_range.high b, t = self.screen.value_range.low, self.screen.value_range.high px = self.process.capture.pixelsize self.process.capture.roi = [l, b, r-l, t-b] def update_data(self): if self.label is not None: self.label.text = self.process.text upd = self.process.data self.data.arrays.update(upd) self.data.data_changed = {"changed": upd.keys()} if self.grid is not None: self.grid.set_data(upd["xbounds"], upd["ybounds"])
class plot_window(HasTraits): _plot_data = Instance(ArrayPlotData) _plot = Instance(Plot) _click_tool = Instance(clicker_tool) _img_plot = Instance(ImagePlot) _right_click_avail = 0 name = Str view = View(Item(name='_plot', editor=ComponentEditor(), show_label=False), ) def __init__(self): # -------------- Initialization of plot system ---------------- padd = 25 self._plot_data = ArrayPlotData() self._x = [] self._y = [] self.man_ori = [1, 2, 3, 4] self._plot = Plot(self._plot_data, default_origin="top left") self._plot.padding_left = padd self._plot.padding_right = padd self._plot.padding_top = padd self._plot.padding_bottom = padd self._quiverplots = [] # ------------------------------------------------------------- def left_clicked_event(self): print("left clicked") if len(self._x) < 4: self._x.append(self._click_tool.x) self._y.append(self._click_tool.y) print self._x print self._y self.drawcross("coord_x", "coord_y", self._x, self._y, "red", 5) self._plot.overlays = [] self.plot_num_overlay(self._x, self._y, self.man_ori) def right_clicked_event(self): print("right clicked") if len(self._x) > 0: self._x.pop() self._y.pop() print self._x print self._y self.drawcross("coord_x", "coord_y", self._x, self._y, "red", 5) self._plot.overlays = [] self.plot_num_overlay(self._x, self._y, self.man_ori) else: if (self._right_click_avail): print "deleting point" self.py_rclick_delete(self._click_tool.x, self._click_tool.y, self.cameraN) x = [] y = [] self.py_get_pix_N(x, y, self.cameraN) self.drawcross("x", "y", x[0], y[0], "blue", 4) def attach_tools(self): self._click_tool = clicker_tool(self._img_plot) self._click_tool.on_trait_change(self.left_clicked_event, 'left_changed') self._click_tool.on_trait_change(self.right_clicked_event, 'right_changed') self._img_plot.tools.append(self._click_tool) self._zoom_tool = SimpleZoom(component=self._plot, tool_mode="box", always_on=False) self._zoom_tool.max_zoom_out_factor = 1.0 self._img_plot.tools.append(self._zoom_tool) if self._plot.index_mapper is not None: self._plot.index_mapper.on_trait_change(self.handle_mapper, 'updated', remove=False) if self._plot.value_mapper is not None: self._plot.value_mapper.on_trait_change(self.handle_mapper, 'updated', remove=False) def drawcross(self, str_x, str_y, x, y, color1, mrk_size): self._plot_data.set_data(str_x, x) self._plot_data.set_data(str_y, y) self._plot.plot((str_x, str_y), type="scatter", color=color1, marker="plus", marker_size=mrk_size) self._plot.request_redraw() def drawline(self, str_x, str_y, x1, y1, x2, y2, color1): self._plot_data.set_data(str_x, [x1, x2]) self._plot_data.set_data(str_y, [y1, y2]) self._plot.plot((str_x, str_y), type="line", color=color1) self._plot.request_redraw() def drawquiver(self, x1c, y1c, x2c, y2c, color, linewidth=1.0, scale=1.0): """ drawquiver draws multiple lines at once on the screen x1,y1->x2,y2 in the current camera window parameters: x1c - array of x1 coordinates y1c - array of y1 coordinates x2c - array of x2 coordinates y2c - array of y2 coordinates color - color of the line linewidth - linewidth of the line example usage: drawquiver ([100,200],[100,100],[400,400],[300,200],'red',linewidth=2.0) draws 2 red lines with thickness = 2 : 100,100->400,300 and 200,100->400,200 """ x1, y1, x2, y2 = self.remove_short_lines(x1c, y1c, x2c, y2c, min_length=0) if len(x1) > 0: xs = ArrayDataSource(x1) ys = ArrayDataSource(y1) quiverplot = QuiverPlot( index=xs, value=ys, index_mapper=LinearMapper(range=self._plot.index_mapper.range), value_mapper=LinearMapper(range=self._plot.value_mapper.range), origin=self._plot.origin, arrow_size=0, line_color=color, line_width=linewidth, ep_index=np.array(x2) * scale, ep_value=np.array(y2) * scale) self._plot.add(quiverplot) # we need this to track how many quiverplots are in the current # plot self._quiverplots.append(quiverplot) # import pdb; pdb.set_trace() def remove_short_lines(self, x1, y1, x2, y2, min_length=2): """ removes short lines from the array of lines parameters: x1,y1,x2,y2 - start and end coordinates of the lines returns: x1f,y1f,x2f,y2f - start and end coordinates of the lines, with short lines removed example usage: x1,y1,x2,y2=remove_short_lines([100,200,300],[100,200,300],[100,200,300],[102,210,320]) 3 input lines, 1 short line will be removed (100,100->100,102) returned coordinates: x1=[200,300]; y1=[200,300]; x2=[200,300]; y2=[210,320] """ # dx, dy = 2, 2 # minimum allowable dx,dy x1f, y1f, x2f, y2f = [], [], [], [] for i in range(len(x1)): if abs(x1[i] - x2[i]) > min_length or abs(y1[i] - y2[i]) > min_length: x1f.append(x1[i]) y1f.append(y1[i]) x2f.append(x2[i]) y2f.append(y2[i]) return x1f, y1f, x2f, y2f def handle_mapper(self): for i in range(0, len(self._plot.overlays)): if hasattr(self._plot.overlays[i], 'real_position'): coord_x1, coord_y1 = self._plot.map_screen( [self._plot.overlays[i].real_position])[0] self._plot.overlays[i].alternate_position = (coord_x1, coord_y1) def plot_num_overlay(self, x, y, txt): for i in range(0, len(x)): coord_x, coord_y = self._plot.map_screen([(x[i], y[i])])[0] ovlay = TextBoxOverlay(component=self._plot, text=str(txt[i]), alternate_position=(coord_x, coord_y), real_position=(x[i], y[i]), text_color="white", border_color="red") self._plot.overlays.append(ovlay) def update_image(self, image, is_float): if is_float: self._plot_data.set_data('imagedata', image.astype(np.float)) else: self._plot_data.set_data('imagedata', image.astype(np.byte)) self._plot.request_redraw()
class ContainerExample(HasTraits): plot = Instance(HPlotContainer) display_button = Button() display_button1 = Button() prev = Button() next = Button() unzoom = Button() traits_view = View( Group(Item('display_button', show_label=False), Item('display_button1', show_label=False), Item('prev', show_label=False), Item('next', show_label=False), Item('unzoom', show_label=False), orientation="horizontal"), Item('plot', editor=ComponentEditor(), show_label=False), # put the info box that lists the mouse location tuple kls karl width=1000, height=600, resizable=True, title="Madagascar Comparison", # How do I activate these? buttons=["do_nothing","do_nothing_1"] ) def __init__(self): super(ContainerExample, self).__init__() # make a list of the files names on the command line # command line entries without = are assumed to be files filenames = [] for parameter in sys.argv[1:]: print("processing parameter", parameter) if parameter.find("=") == -1: print("no = in parameter", parameter, "must be a file name") filenames.append(parameter) if len(filenames) < 1: print("just to help me test, if there are no files in the list, ") print("I will append the file foldplot1.rsf") filenames.append('foldplot1.rsf') # there should be a try while these files are opened to identify # bad file names and make error messages. self.seis_data = [] for filename in filenames: print(" ") print("+++++++++++++++++++++++++++++++++++++++++++") print("+++++++++++++++++++++++++++++++++++++++++++") print("open the file", filename) self.seis_data.append(SeisData(filename)) # kls files should be tested to make sure they are all same shape print("number files=", len(filenames)) self.displayParameters = DisplayParameters() self.cmap = jet # kls this should come from display parameters self.slice_y = self.displayParameters.slice_y # kls this should be pointer print("self.slice_y=", self.slice_y) self.arrayPlotDatas = [] for filename in filenames: self.arrayPlotDatas.append(ArrayPlotData()) self._update_images() x_extents = (self.seis_data[0].axis_start[1], self.seis_data[0].axis_end[1]) y_extents = (self.seis_data[0].axis_start[2], self.seis_data[0].axis_end[2]) bottomplot = Plot(self.arrayPlotDatas[0], origin="top left") self.bottomplot = bottomplot imgplot = bottomplot.img_plot("xz", xbounds=x_extents, ybounds=y_extents, colormap=self.cmap)[0] self.bottom = imgplot plotright = Plot(self.arrayPlotDatas[1], origin="top left", range2d=bottomplot.range2d) imgplotright = plotright.img_plot("xz", xbounds=x_extents, ybounds=y_extents, colormap=self.cmap)[0] self.right = imgplotright container = HPlotContainer(fill_padding=True, bgcolor="white", use_backbuffer=True) container.add(bottomplot) container.add(plotright) self.plot = container self.displayParameters = DisplayParameters() self.slice_y = self.displayParameters.slice_y imgplot.tools.append(CustomTool(imgplot)) imgplot.tools.append(PanTool(imgplot, constrain_key="shift")) imgplot.overlays.append( ZoomTool(component=imgplot, tool_mode="box", always_on=False)) imgplotright.tools.append(PanTool(imgplotright, constrain_key="shift")) imgplotright.overlays.append( ZoomTool(component=self.right, tool_mode="box", always_on=False)) def _update_image(self, number): if self.displayParameters.gain != 0: rgain = 1. / self.displayParameters.gain else: rgain = 1 print("rgain=", rgain) range = DataRange1D(low=self.seis_data[number].minval * rgain, high=self.seis_data[number].maxval * rgain) self.colormap = self.cmap(range) slice = transpose(self.seis_data[number].vals[self.slice_y, :, :]) self.slice = slice colorslice = (self.colormap.map_screen(slice) * 255).astype(uint8) # Transposed required because img_plot() expects data in row-major order # self.arrayPlotData.set_data("xz", colorslicexz) self.arrayPlotDatas[number].set_data("xz", colorslice) def _update_images(self): for imageindex in range(len(self.seis_data)): self._update_image(imageindex) def _marker_size_changed(self): self.scatter.marker_size = self.marker_size def _color_changed(self): self.scatter.marker_size = self.marker_size def _display_button_fired(self): print("Display button pushed") self.displayParameters.edit_traits() self._update_images() def _prev_fired(self): print("prev button pushed") slice_y = self.slice_y - self.displayParameters.slice_inc if (slice_y < 0): slice_y = self.seis_data[0].vals.shape[0] - 1 print("after decrement slice_y=", slice_y) self.slice_y = slice_y self._update_images() def _next_fired(self): print("next button pushed") slice_y = self.slice_y + self.displayParameters.slice_inc print("shape=", self.seis_data[0].vals.shape) if (slice_y >= self.seis_data[0].vals.shape[0]): slice_y = 0 print("after increment slice_y=", slice_y) self.slice_y = slice_y self._update_images() def _unzoom_fired(self): print("unzoom button pushed") print("self.bottomplot.range2d=", self.bottomplot.range2d) print("xmin/xmax=", \ self.bottomplot.range2d.x_range.low, \ self.bottomplot.range2d.x_range.high) print("ymin/ymax=", \ self.bottomplot.range2d.y_range.low, \ self.bottomplot.range2d.y_range.high) self.bottomplot.range2d.x_range.low = self.seis_data[0].axis_start[1] self.bottomplot.range2d.x_range.high = self.seis_data[0].axis_end[1] self.bottomplot.range2d.y_range.low = self.seis_data[0].axis_start[2] self.bottomplot.range2d.y_range.high = self.seis_data[0].axis_end[2]
class PricePlot(HasTraits): plot = Instance(Plot) traits_view = View( Item('plot', editor=ComponentEditor(), show_label=False), width=1200, height=1000, resizable=True, title="Bitcoin Prices") def __init__(self, time, buy, sell, weighted_buy, weighted_sell): t = numpy.array(time) # Convert lists to numpy arrays in preparation for plotting b = numpy.array(buy) s = numpy.array(sell) wb = numpy.array(weighted_buy) ws = numpy.array(weighted_sell) self.t = t self.b = b self.s = s plot_data = ArrayPlotData(t=t, b=b, s=s, wb=wb, ws=ws) plot = Plot(plot_data) self.plot = plot # Calculate range of plot so it shows latest 1 day of data end = t[-1] start = end - 86400 self._configure_plot(plot, start, end) # Scatter point for prices buy_renderer = plot.plot(("t", "b"), type="scatter", color=RED)[0] sell_renderer = plot.plot(("t", "s"), type="scatter", color=GREEN)[0] # Line plot to connect the scatter points together plot.plot(("t", "b"), type="line", color=LIGHT_RED) # Using RGBA color tuple to get a lighter color plot.plot(("t", "s"), type="line", color=LIGHT_GREEN) # Line plot of moving average of prices (thicker to indicate this fact) plot.plot(("t", "wb"), type="line", color=RED, line_width=2) plot.plot(("t", "ws"), type="line", color=GREEN, line_width=2) buy_renderer.marker_size = 3 buy_renderer.marker = "circle" sell_renderer.marker_size = 3 sell_renderer.marker = "circle" plot.title = "Current Price - Buy: ${} - Sell: ${}".format(buy[-1], sell[-1]) # Display current price in title def _configure_plot(self, plot, start, end): """ Configures the appearance of the plot """ plot.bgcolor = "black" plot.title_color = "white" plot.y_axis.orientation = "right" plot.y_axis.tick_color = "white" plot.y_axis.tick_label_color = "white" plot.x_axis.tick_color = "white" plot.x_axis.tick_label_color = "white" plot.x_grid.line_weight = 0 # Remove x Grid lines pan = PanTool(component=plot) # Set up PanTool so that it is constrained to move along the x-direction only pan.constrain = True pan.constrain_direction = 'x' plot.tools.append(pan) # Add Pan and Zoom abilities to the plot zoom = ZoomTool(component=plot, tool_mode="range", axis="index", always_on=False) # We create the ZoomTool to zoom along the x-axis only plot.tools.append(zoom) plot.x_axis.tick_label_formatter = lambda tick: self._format_time(tick) # Set formatter for time axis tick labels plot.index_mapper.range.set_bounds(start, end) # Set range of index (x values i.e. domain) plot.index_mapper.range.on_trait_change(self._xrange_changed, name='_low_value') # We attach a listener on the range that is called when the _low_value attribute is changed self._xrange_changed() # We call this initially to fit the y-range initially def _y_bounds(self): """ Calculates the min and max values of the arrays b and s in the x-range currently chosen """ (a, b) = self.plot.index_mapper.range.bound_data(self.t) # We find the indices that bound the data self.t in the currently chosen x_range min = 1e6 # Start with a maximum possible value from which to go down max = 0 for jj in range(a, b): # We iterate over the indices of the bounds finding the min and max values of self.b and self.s in the range if self.b[jj] < min: min = self.b[jj] if self.s[jj] < min: min = self.s[jj] if self.b[jj] > max: max = self.b[jj] if self.s[jj] > max: max = self.b[jj] return min, max def _xrange_changed(self): """ Method called when the xrange is changed so that the yrange can be changed to better fit the y-values """ # Calculate the highest and lowest value of the graphs in the specified x-range. (y_min, y_max) = self._y_bounds() delta = 0.1 * (y_max - y_min) # We calculate margins on the bound using 10% of the data-spread self.plot.value_mapper.range.set_bounds(y_min - delta, y_max + delta) def _format_time(self, time): """ Method for taking the Unix timestamp in the time-series domain and converting it in to a human-readable format """ return datetime.datetime.fromtimestamp(time).strftime("%m-%d %H:%M")
class MyPlot(HasTraits): """ Displays a plot with a few buttons to control which overlay to display """ plot = Instance(Plot) status_overlay = Instance(StatusLayer) error_button = Button('Error') warn_button = Button('Warning') no_problem_button = Button('No problem') traits_view = View( HGroup(UItem('error_button'), UItem('warn_button'), UItem('no_problem_button')), UItem('plot', editor=ComponentEditor()), width=700, height=600, resizable=True, ) def __init__(self, index, data_series, **kw): super(MyPlot, self).__init__(**kw) plot_data = ArrayPlotData(index=index) plot_data.set_data('data_series', data_series) self.plot = Plot(plot_data) self.plot.plot(('index', 'data_series')) def _error_button_fired(self, event): """ removes the old overlay and replaces it with an error overlay """ self.clear_status() self.status_overlay = ErrorLayer(component=self.plot, align='ul', scale_factor=0.25) self.plot.overlays.append(self.status_overlay) self.plot.request_redraw() def _warn_button_fired(self, event): """ removes the old overlay and replaces it with an warning overlay """ self.clear_status() self.status_overlay = WarningLayer(component=self.plot, align='ur', scale_factor=0.25) self.plot.overlays.append(self.status_overlay) self.plot.request_redraw() def _no_problem_button_fired(self, event): """ removes the old overlay """ self.clear_status() self.plot.request_redraw() def clear_status(self): if self.status_overlay in self.plot.overlays: # fade_out will remove the overlay when its done self.status_overlay.fade_out()
class ContainerExample(HasTraits): plot = Instance(Plot) display_button = Button() display_button1 = Button() traits_view = View(Group(Item('display_button', show_label=False), Item('display_button1', show_label=False), orientation="horizontal"), Item('plot', editor=ComponentEditor(), show_label=False), width=1000, height=600, resizable=True, title="Chaco Plot", buttons=["prev", "next", "new data"]) def __init__(self): super(ContainerExample, self).__init__() filenames = [] for parameter in sys.argv[1:]: print("processing parameter", parameter) if parameter.find("=") == -1: print("no = in parameter", parameter, "must be a file name") filenames.append(parameter) if len(filenames) < 1: print("just to help me test, if there are no files in the list, ") print("I will append the file foldplot1.rsf") filenames.append('foldplot1.rsf') self.seis_data_0 = SeisData(filenames[0]) self.cmap = jet self.displayParameters = DisplayParameters() self.slice_y = self.displayParameters.slice_y print("self.slice_y=", self.slice_y) self.arrayPlotData = ArrayPlotData() self._update_images() bottomplot = Plot(self.arrayPlotData, padding=0, origin="top left") imgplot = bottomplot.img_plot("xz", xbounds=(self.seis_data_0.axis_start[0], self.seis_data_0.axis_end[0]), ybounds=(self.seis_data_0.axis_start[2], self.seis_data_0.axis_end[2]), colormap=self.cmap)[0] self.bottom = imgplot print("x range=", self.seis_data_0.axis_start[0], self.seis_data_0.axis_end[0]) print("z range=", self.seis_data_0.axis_start[2], self.seis_data_0.axis_end[2]) #print "colormap.shape=',colormap.shape) x = linspace(-14, 14, 100) y = x**3 plotdata = ArrayPlotData(x=x, y=y) scatter = Plot(plotdata, origin="top left") scatter.plot(("x", "y"), type="scatter", color='blue') scatter.title = "x**3" self.scatter = scatter #scatter.origin="top left" print("make container") container = HPlotContainer(bottomplot) print("container.add") container.add(scatter) #container.spacing = 0 # scatter.padding_right = 0 # line.padding_left = 0 # line.y_axis.orientation = "right" self.plot = bottomplot #container # kls karl !! When I change plot = Instance(Plot) and this line to # self.plot=container I get no img_plotplot to # self.plot.tools.append(CustomTool(self.plot)) self.displayParameters = DisplayParameters() imgplot.tools.append(CustomTool(self.plot)) def _update_images(self): range = DataRange1D(low=self.seis_data_0.minval, high=self.seis_data_0.maxval) print("self.seis_data_0.min/max=", self.seis_data_0.minval, self.seis_data_0.maxval) self.colormap = self.cmap(range) print("self.slice_y=", self.slice_y) slicexz = self.seis_data_0.vals[:, self.slice_y, :] print("min/max slicexz=", min(slicexz), max(slicexz)) colorslicexz = (self.colormap.map_screen(slicexz) * 255).astype(uint8) # Transposed required because img_plot() expects data in row-major order # self.arrayPlotData.set_data("xz", transpose(colorslicexz,(1,0,2))) self.arrayPlotData.set_data("xz", colorslicexz) print("colorslicexz.shape=", colorslicexz.shape) print("type(colorslicexz)=", type(colorslicexz)) print("type(colorslicexz[0,0,0])=", type(colorslicexz[0, 0, 0])) print("colorslicexz=", colorslicexz) print("min(colorslicexz[0,:,:,:]=", min(colorslicexz[:, :, 0])) print("min(colorslicexz[1,:,:,:]=", min(colorslicexz[:, :, 1])) print("min(colorslicexz[2,:,:,:]=", min(colorslicexz[:, :, 2])) print("min(colorslicexz[3,:,:,:]=", min(colorslicexz[:, :, 3])) def _marker_size_changed(self): self.scatter.marker_size = self.marker_size def _color_changed(self): self.scatter.marker_size = self.marker_size def _display_button_fired(self): print("button pushed") self.displayParameters.edit_traits() def _next_fired(self): print("next button pushed")
class HintonDiagramPlot(PyannoPlotContainer): """Defines a Hinton diagram view of a discrete probability distribution. A Hinton diagram displays a probability distribution as a series of squares, with area proportional to the probability mass of each element. The plot updates automatically whenever the attribute `data` is modified. """ #### Traits definition #################################################### # data to be displayed data = ListFloat #### plot-related traits plot_data = Instance(ArrayPlotData) plot = Any @on_trait_change('data', post_init=True) def _update_data(self): distr_len = len(self.data) plot_data = self.plot_data # centers of the squares centers = [(i, 0.5) for i in xrange(1, distr_len + 1)] for idx, center in enumerate(centers): # draw square with area proportional to probability mass r = np.sqrt(self.data[idx] / (2. * np.pi)) npoints = n_gon(center=center, r=r, nsides=40) nxarray, nyarray = np.transpose(npoints) # save in dataarray plot_data.set_data('x%d' % idx, nxarray) plot_data.set_data('y%d' % idx, nyarray) def _plot_data_default(self): self.plot_data = ArrayPlotData() self._update_data() return self.plot_data #### Plot definition ###################################################### def _create_probability_axis(self, plot): """Create plot axis for probability values.""" prob_axis = LabelAxis(plot, orientation='left', positions=[0.5, 0.5 + np.sqrt(0.25) / 2., 1.0], labels=['0', '0.25', '1']) prob_axis.tick_generator = ScalesTickGenerator(scale=FixedScale(0.001)) return prob_axis def _plot_default(self): distr_len = len(self.data) # PolygonPlot holding the circles of the Hinton diagram polyplot = Plot(self.plot_data) for idx in range(distr_len): p = polyplot.plot(('x%d' % idx, 'y%d' % idx), type="polygon", face_color=get_class_color(idx), edge_color='black') self._set_title(polyplot) self._remove_grid_and_axes(polyplot) # create x axis for labels axis = self._create_increment_one_axis(polyplot, 1., distr_len, 'bottom') self._add_index_axis(polyplot, axis) # create y axis for probability density #prob_axis = self._create_probability_axis(polyplot) #polyplot.value_axis = prob_axis #polyplot.underlays.append(prob_axis) # tweak some of the plot properties range2d = DataRange2D(low=(0.5, 0.), high=(distr_len + 0.5, 1.)) polyplot.range2d = range2d polyplot.aspect_ratio = ((range2d.x_range.high - range2d.x_range.low) / (range2d.y_range.high - range2d.y_range.low)) polyplot.border_visible = False polyplot.padding = [0, 0, 25, 25] # create a container to position the plot and the colorbar side-by-side container = HPlotContainer(use_backbuffer=True, valign='center') container.add(polyplot) container.bgcolor = 0xFFFFFF # light gray: 0xEEEEEE self.decorate_plot(container, self.data) return container #### View definition ###################################################### resizable_plot_item = Item('plot', editor=ComponentEditor(), resizable=True, show_label=False, width=600, height=400) traits_plot_item = Instance(Item) def _traits_plot_item_default(self): return Item( 'plot', editor=ComponentEditor(), resizable=False, show_label=False, height=-110, )
class ConnectedRange(HasTraits): model = Instance(imageModel) upper = DelegatesTo('model') lower = DelegatesTo('model') c = DelegatesTo('model') lowerLimit = DelegatesTo('model') upperLimit = DelegatesTo('model') img = DelegatesTo('model') hist = DelegatesTo('model') lowerFilt = DelegatesTo('model') upperFilt = DelegatesTo('model') edges = DelegatesTo('model') fill = DelegatesTo('model') elevation = DelegatesTo('model') markers = DelegatesTo('model') segmentation = DelegatesTo('model') container01 = Instance(HPlotContainer) container02 = Instance(HPlotContainer) imgdata = Instance(ArrayPlotData) upfilt = Instance(ArrayPlotData) lowfilt = Instance(ArrayPlotData) edgesPlot = Instance(ArrayPlotData) fillPlot = Instance(ArrayPlotData) elevPlot = Instance(ArrayPlotData) markerPlot = Instance(ArrayPlotData) segmentationPlot = Instance(ArrayPlotData) traits_view = View(Item('container01', editor=ComponentEditor(), show_label=False), Item('container02', editor=ComponentEditor(), show_label=False), Item('upper', editor=RangeEditor(low=0., high=240.), label="upperbound"), Item('lower', editor=RangeEditor(low=0., high=240.), label="lowerbound"), Item('lowerLimit', editor=RangeEditor(low=0., high=256.), label="lowerLimit"), Item('upperLimit', editor=RangeEditor(low=0., high=256.), label="upperLimit"), Item('c', editor=RangeEditor(low=-5., high=5.)), resizable=True, title="Connected Range") def _imgdata_default(self): img = self.img imgdata = ArrayPlotData(imagedata=img, colormap=gray) return imgdata def _upfilt_default(self): img = self.upperFilt imgdata = ArrayPlotData(imagedata=img, colormap=gray) return imgdata def _lowfilt_default(self): img = self.lowerFilt imgdata = ArrayPlotData(imagedata=img, colormap=gray) return imgdata def _edgesPlot_default(self): edges = self.edges imgdata = ArrayPlotData(imagedata=edges, colormap=gray) return imgdata def _fillPlot_default(self): fill = self.fill imgdata = ArrayPlotData(imagedata=fill, colormap=gray) return imgdata def _elevPlot_default(self): elev = self.elevation imgdata = ArrayPlotData(imagedata=elev) return imgdata def _markerPlot_default(self): markers = self.markers imgdata = ArrayPlotData(imagedata=markers) return imgdata def _segmentationPlot_default(self): segmentation = self.segmentation imgdata = ArrayPlotData(imagedata=segmentation) return imgdata def _container02_default(self): # Create the data and the PlotData object fillPlot = self.fillPlot fill = Plot(fillPlot) fill.img_plot("imagedata", colormap=gray) elev = Plot(self.elevPlot) elev.img_plot("imagedata", colormap=gray) marker = Plot(self.markerPlot) marker.img_plot("imagedata", colormap=gray) segmentation = Plot(self.segmentationPlot) segmentation.img_plot("imagedata", colormap=gray) return HPlotContainer(fill, elev, marker, segmentation) def _container01_default(self): # Create the data and the PlotData object imgdata = self.imgdata upperfilter = self.upfilt lowerfilter = self.lowfilt edgesPlot = self.edgesPlot # Create the scatter plot scatter = Plot(imgdata) scatter.img_plot("imagedata", colormap=gray) # Create the line plot line = Plot(upperfilter) line.img_plot("imagedata", colormap=gray) # Create the other line plot line2 = Plot(lowerfilter) line2.img_plot("imagedata", colormap=gray) #create edges edgeplot = Plot(edgesPlot) edgeplot.img_plot("imagedata", colormap=gray) # Add pan/zoom so we can see they are connected scatter.tools.append(PanTool(scatter)) scatter.tools.append(ZoomTool(scatter)) line.tools.append(PanTool(line)) line.tools.append(ZoomTool(line)) line2.tools.append(PanTool(line)) line2.tools.append(ZoomTool(line)) # Set the two plots' ranges to be the same #scatter.index_range = line.index_range #scatter.value_range = line.value_range ##set manually with scatter.value_range.set_bounds(0,1) ##or scatter.index_range.set_bounds(0,1) # Create a horizontal container and put the two plots inside it return HPlotContainer(scatter, line, line2, edgeplot) @on_trait_change('img') def update_img(self): self.imgdata.set_data('imagedata', self.img) @on_trait_change('upperFilt') def update_upperFilter(self): self.upfilt.set_data('imagedata', self.upperFilt) @on_trait_change('lowerFilt') def update_lowerFilter(self): self.lowfilt.set_data('imagedata', self.lowerFilt) @on_trait_change('edges') def update_edges(self): self.edgesPlot.set_data('imagedata', self.edges) @on_trait_change('fill') def update_fill(self): self.fillPlot.set_data('imagedata', self.fill) @on_trait_change('elevation') def update_elevation(self): self.elevPlot.set_data('imagedata', self.elevation) @on_trait_change('markers') def update_markers(self): self.markerPlot.set_data('imagedata', self.markers) @on_trait_change('segmentation') def update_segmentation(self): self.segmentationPlot.set_data('imagedata', self.segmentation)
def traits_view(self): cali_grp = VGroup(UItem( 'tray_manager.calibrate', enabled_when='stage_manager.stage_map_name', editor=ButtonEditor(label_value='tray_manager.calibration_step')), HGroup( Readonly('tray_manager.x', format_str='%0.3f'), Readonly('tray_manager.y', format_str='%0.3f')), Readonly('tray_manager.rotation', format_str='%0.3f'), Readonly('tray_manager.scale', format_str='%0.4f'), Readonly('tray_manager.error', format_str='%0.2f'), UItem('tray_manager.calibrator', style='custom', editor=InstanceEditor()), CustomLabel('tray_manager.calibration_help', color='green', height=75, width=300), show_border=True, label='Calibration') # c_grp = VGroup(HGroup(Item('setpoint'), # UItem('setpoint_readback')), # UItem('setpoint_readback', # enabled_when='0', # editor=RangeEditor(mode='slider', # low_name='setpoint_readback_min', # high_name='setpoint_readback_max')), # # label='Controller', show_border=True) c_grp = VGroup(Item('setpoint'), VGroup(UItem('setpoint_readback', editor=LCDEditor())), label='Controller', show_border=True) d_grp = VGroup( Item('stage_manager.calibrated_position_entry', label='Hole'), Item('stage_manager.sample_linear_holder.position', editor=RangeEditor( mode='slider', low_name='stage_manager.sample_linear_holder.min_value', high_name='stage_manager.sample_linear_holder.max_value', )), HGroup( UItem('pane.dump_sample_button', tooltip='Complete sample dumping procedure'), icon_button_editor('pane.funnel_up_button', 'arrow_up', enabled_when='pane.funnel_up_enabled', editor_kw={'label': 'Funnel Up'}), icon_button_editor('pane.funnel_down_button', 'arrow_down', enabled_when='pane.funnel_down_enabled', editor_kw={'label': 'Funnel Down'}), spring), UItem('dumper_canvas', editor=ComponentEditor()), # UItem('pane.lower_funnel_button', enabled_when='stage_manager.funnel.min_limit'), # UItem('pane.raise_funnel_button', enabled_when='stage_manager.funnel.max_limit'), label='Dumper', show_border=True) v = View(VGroup(c_grp, HGroup(Tabbed(d_grp, cali_grp)))) return v
def traits_view(self): v = View(VGroup(HGroup(Item('irradiation_tray', style='readonly')), UItem('canvas', editor=ComponentEditor()))) return v
def traits_view(self): ctrl_grp = VGroup( Item('path', show_label=False), Item('highlight_bands', editor=ListEditor(mutable=False, style='custom', editor=InstanceEditor()))) v = View( ctrl_grp, Item('container', show_label=False, editor=ComponentEditor()), # title='Color Inspector', resizable=True, height=800, width=900) return v # def traits_view(self): # lgrp = VGroup(Item('low'), # Item('low', show_label=False, editor=RangeEditor(mode='slider', low=0, high_name='high'))) # hgrp = VGroup(Item('high'), # Item('high', show_label=False, editor=RangeEditor(mode='slider', low_name='low', high=255))) # savegrp = HGroup(Item('save_button', show_label=False), # Item('save_mode', show_label=False)) # ctrlgrp = VGroup( # Item('path', show_label=False), # HGroup(Item('use_threshold'), Item('contrast_equalize'), # HGroup(Item('contrast_low'), Item('contrast_high'), enabled_when='contrast_equalize'), # Item('histogram_equalize') # ), # HGroup(Item('highlight'), Item('highlight_threshold')), # HGroup(spring, # lgrp, # hgrp, # VGroup(savegrp, # Item('calc_area_value', label='Calc. Area For.', # tooltip='Calculate %area for all pixels with this value' # ), # Item('calc_area_threshold', label='Threshold +/- px', # tooltip='bandwidth= calc_value-threshold to calc_value+threshold' # ) # # ) # ), # HGroup(spring, Item('area', style='readonly', width= -200)), # HGroup( # Item('colormap_name_1', show_label=False, # editor=EnumEditor(values=color_map_name_dict.keys())), # spring, # Item('colormap_name_2', show_label=False, # editor=EnumEditor(values=color_map_name_dict.keys()))), # ) # v = View(ctrlgrp, # Item('container', show_label=False, # editor=ComponentEditor()), # # title='Color Inspector', # resizable=True, # height=800, # width=900 # # ) return v
class PlotUI(HasTraits): # container for all plots container = Instance(HPlotContainer) # Plot components within this container: polyplot = Instance(ContourPolyPlot) lineplot = Instance(ContourLinePlot) cross_plot = Instance(Plot) cross_plot2 = Instance(Plot) colorbar = Instance(ColorBar) # plot data pd = Instance(ArrayPlotData) # view options num_levels = Int(15) colormap = Enum(colormaps) #Traits view definitions: traits_view = View(Group( UItem('container', editor=ComponentEditor(size=(800, 600)))), resizable=True) plot_edit_view = View(Group(Item('num_levels'), Item('colormap')), buttons=["OK", "Cancel"]) #--------------------------------------------------------------------------- # Private Traits #--------------------------------------------------------------------------- _image_index = Instance(GridDataSource) _image_value = Instance(ImageData) _cmap = Trait(default_colormaps.jet, Callable) #--------------------------------------------------------------------------- # Public View interface #--------------------------------------------------------------------------- def __init__(self, *args, **kwargs): super(PlotUI, self).__init__(*args, **kwargs) # FIXME: 'with' wrapping is temporary fix for infinite range in initial # color map, which can cause a distracting warning print. This 'with' # wrapping should be unnecessary after fix in color_mapper.py. with errstate(invalid='ignore'): self.create_plot() def create_plot(self): # Create the mapper, etc self._image_index = GridDataSource(array([]), array([]), sort_order=("ascending", "ascending")) image_index_range = DataRange2D(self._image_index) self._image_index.on_trait_change(self._metadata_changed, "metadata_changed") self._image_value = ImageData(data=array([]), value_depth=1) image_value_range = DataRange1D(self._image_value) # Create the contour plots self.polyplot = ContourPolyPlot(index=self._image_index, value=self._image_value, index_mapper=GridMapper(range= image_index_range), color_mapper=\ self._cmap(image_value_range), levels=self.num_levels) self.lineplot = ContourLinePlot( index=self._image_index, value=self._image_value, index_mapper=GridMapper(range=self.polyplot.index_mapper.range), levels=self.num_levels) # Add a left axis to the plot left = PlotAxis(orientation='left', title="y", mapper=self.polyplot.index_mapper._ymapper, component=self.polyplot) self.polyplot.overlays.append(left) # Add a bottom axis to the plot bottom = PlotAxis(orientation='bottom', title="x", mapper=self.polyplot.index_mapper._xmapper, component=self.polyplot) self.polyplot.overlays.append(bottom) # Add some tools to the plot self.polyplot.tools.append( PanTool(self.polyplot, constrain_key="shift")) self.polyplot.overlays.append( ZoomTool(component=self.polyplot, tool_mode="box", always_on=False)) self.polyplot.overlays.append( LineInspector(component=self.polyplot, axis='index_x', inspect_mode="indexed", write_metadata=True, is_listener=True, color="white")) self.polyplot.overlays.append( LineInspector(component=self.polyplot, axis='index_y', inspect_mode="indexed", write_metadata=True, color="white", is_listener=True)) # Add these two plots to one container contour_container = OverlayPlotContainer(padding=20, use_backbuffer=True, unified_draw=True) contour_container.add(self.polyplot) contour_container.add(self.lineplot) # Create a colorbar cbar_index_mapper = LinearMapper(range=image_value_range) self.colorbar = ColorBar(index_mapper=cbar_index_mapper, plot=self.polyplot, padding_top=self.polyplot.padding_top, padding_bottom=self.polyplot.padding_bottom, padding_right=40, resizable='v', width=30) self.pd = ArrayPlotData(line_index=array([]), line_value=array([]), scatter_index=array([]), scatter_value=array([]), scatter_color=array([])) self.cross_plot = Plot(self.pd, resizable="h") self.cross_plot.height = 100 self.cross_plot.padding = 20 self.cross_plot.plot(("line_index", "line_value"), line_style="dot") self.cross_plot.plot( ("scatter_index", "scatter_value", "scatter_color"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=8) self.cross_plot.index_range = self.polyplot.index_range.x_range self.pd.set_data("line_index2", array([])) self.pd.set_data("line_value2", array([])) self.pd.set_data("scatter_index2", array([])) self.pd.set_data("scatter_value2", array([])) self.pd.set_data("scatter_color2", array([])) self.cross_plot2 = Plot(self.pd, width=140, orientation="v", resizable="v", padding=20, padding_bottom=160) self.cross_plot2.plot(("line_index2", "line_value2"), line_style="dot") self.cross_plot2.plot( ("scatter_index2", "scatter_value2", "scatter_color2"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=8) self.cross_plot2.index_range = self.polyplot.index_range.y_range # Create a container and add components self.container = HPlotContainer(padding=40, fill_padding=True, bgcolor="white", use_backbuffer=False) inner_cont = VPlotContainer(padding=0, use_backbuffer=True) inner_cont.add(self.cross_plot) inner_cont.add(contour_container) self.container.add(self.colorbar) self.container.add(inner_cont) self.container.add(self.cross_plot2) def update(self, model): self.minz = model.minz self.maxz = model.maxz self.colorbar.index_mapper.range.low = self.minz self.colorbar.index_mapper.range.high = self.maxz self._image_index.set_data(model.xs, model.ys) self._image_value.data = model.zs self.pd.set_data("line_index", model.xs) self.pd.set_data("line_index2", model.ys) self.container.invalidate_draw() self.container.request_redraw() #--------------------------------------------------------------------------- # Event handlers #--------------------------------------------------------------------------- def _metadata_changed(self, old, new): """ This function takes out a cross section from the image data, based on the line inspector selections, and updates the line and scatter plots.""" self.cross_plot.value_range.low = self.minz self.cross_plot.value_range.high = self.maxz self.cross_plot2.value_range.low = self.minz self.cross_plot2.value_range.high = self.maxz if self._image_index.metadata.has_key("selections"): x_ndx, y_ndx = self._image_index.metadata["selections"] if y_ndx and x_ndx: self.pd.set_data("line_value", self._image_value.data[y_ndx, :]) self.pd.set_data("line_value2", self._image_value.data[:, x_ndx]) xdata, ydata = self._image_index.get_data() xdata, ydata = xdata.get_data(), ydata.get_data() self.pd.set_data("scatter_index", array([xdata[x_ndx]])) self.pd.set_data("scatter_index2", array([ydata[y_ndx]])) self.pd.set_data("scatter_value", array([self._image_value.data[y_ndx, x_ndx]])) self.pd.set_data("scatter_value2", array([self._image_value.data[y_ndx, x_ndx]])) self.pd.set_data("scatter_color", array([self._image_value.data[y_ndx, x_ndx]])) self.pd.set_data("scatter_color2", array([self._image_value.data[y_ndx, x_ndx]])) else: self.pd.set_data("scatter_value", array([])) self.pd.set_data("scatter_value2", array([])) self.pd.set_data("line_value", array([])) self.pd.set_data("line_value2", array([])) def _colormap_changed(self): self._cmap = default_colormaps.color_map_name_dict[self.colormap] if self.polyplot is not None: value_range = self.polyplot.color_mapper.range self.polyplot.color_mapper = self._cmap(value_range) value_range = self.cross_plot.color_mapper.range self.cross_plot.color_mapper = self._cmap(value_range) # FIXME: change when we decide how best to update plots using # the shared colormap in plot object self.cross_plot.plots["dot"][0].color_mapper = self._cmap( value_range) self.cross_plot2.plots["dot"][0].color_mapper = self._cmap( value_range) self.container.request_redraw() def _num_levels_changed(self): if self.num_levels > 3: self.polyplot.levels = self.num_levels self.lineplot.levels = self.num_levels
class Viewport(Handler): ds = Any #FIXME there is no reason to have modular viewports anymore since as #it turns out the viewport has to be rebuilt in order to update the view. #this is something that could be modularly managed. #The benefit of changing what now works is however low. It is basically #a very weak form of static type checking, and a way to save a miniscule #amount of time and space on managing pointers. #by keeping these views on the viewport object itself, we can change #the dataset without making traitsui think that the view is inaccessible #and it is time to be thrown away immediately upon loading a new dataset scene = Instance(MlabSceneModel) conn_mat = Instance(Plot) circ = Instance(Figure) view_type = Enum('dummy', '3D Brain', 'Connection Matrix', 'Circular plot') dummy_view = View( Item(editor=NullEditor(), height=500, width=500, label='empty')) mayavi_view = View( Item(name='scene', editor=SceneEditor(scene_class=MayaviScene), height=500, width=500, show_label=False, resizable=True)) matrix_view = View( Item(name='conn_mat', editor=ComponentEditor(), height=500, width=500, show_label=False, resizable=True)) circle_view = View( Item(name='circ', editor=MPLFigureEditor(), height=500, width=500, show_label=False, resizable=True)) def __init__(self, ds, **kwargs): super(Viewport, self).__init__(**kwargs) self.ds = ds #it is ok to assign the editors while initializing the viewport self.scene = ds.dv_3d.scene self.conn_mat = ds.dv_mat.conn_mat self.circ = ds.dv_circ.circ #MPLEditor wants its interactions to be on the model object #this is the "fake" model object so we forward them to the real model object def circle_click(self, event): self.ds.dv_circ.circle_click(event) def circle_mouseover(self, event, tooltip): self.ds.dv_circ.circle_mouseover(event, tooltip)
class MyImagePlot(HasTraits): # define plot as a trait plot = Instance(GridPlotContainer) my_position = Tuple(0, 0) off_grid = Bool(False) my_data_bounds = Range(low=50, high=250) # subset of image matrix submatrix = Array(shape=(my_data_bounds.value, my_data_bounds.value)) # histogram and bin edge locations hist = Array() bin_edges = Array() traits_view = View(Item('my_data_bounds'), Item( 'plot', editor=ComponentEditor(), width=500, height=500, ), title='Image:', width=800, height=600) def __init__(self, image): self.im = image self.plot_constructors = [ self.image_histogram_plot_component, self.intensity_histogram_plot_component, ] self.submatrix = self.im[0:self.my_data_bounds, 0:self.my_data_bounds] self.hist, self.bin_edges = calculate_intensity_histogram( self.submatrix) def _plot_default(self): return self.grid_plot_component() def grid_plot_component(self): container = GridPlotContainer(padding=50, fill_padding=True, shape=(1, len(self.plot_constructors)), spacing=(20, 20)) for plot_constructor in self.plot_constructors: plot = plot_constructor() container.add(plot) return container def image_histogram_plot_component(self): xs = np.arange(0, len(self.im)) ys = np.arange(0, len(self.im[0])) index = GridDataSource(xdata=xs, ydata=ys, sort_order=('ascending', 'ascending')) index_mapper = GridMapper(range=DataRange2D(index)) color_source = ImageData(data=self.im, value_depth=1) reversed_grays = reverse(Greys) color_mapper = reversed_grays(DataRange1D(color_source)) plot = CMapImagePlot( index=index, index_mapper=index_mapper, value=color_source, value_mapper=color_mapper, orientation='h', origin='top left', ) self.data_box_overlay = DataBox( component=plot, data_position=[0, 0], data_bounds=[self.my_data_bounds, self.my_data_bounds], ) move_tool = MoveTool(component=self.data_box_overlay) self.data_box_overlay.tools.append(move_tool) self.data_box_overlay.on_trait_change(self.update_my_position, 'position') #: Add to plot plot.overlays.append(self.data_box_overlay) return plot def intensity_histogram_plot_component(self): data = ArrayPlotData(x=self.bin_edges, y=self.hist) plot = Plot(data) plot.plot( ('x', "y"), type='bar', color='auto', bar_width=1, ) # without padding plot just doesn't seem to show up? plot.padding = 0 return plot def update_my_position(object, new): try: object.my_position = object.plot._components[0].map_index(new) object.off_grid = False except TraitError: object.off_grid = True def _my_data_bounds_changed(self): if not self.off_grid: self.data_box_overlay.data_bounds = [ self.my_data_bounds, self.my_data_bounds ] self.data_box_overlay._data_position = self.my_position def _my_position_changed(self, new): self.submatrix = self.im[new[0]:new[0] + self.my_data_bounds, new[1]:new[1] + self.my_data_bounds] def _submatrix_changed(self, new): self.hist, self.bin_edges = calculate_intensity_histogram(new) def _bin_edges_changed(self): self.plot._components[1].data.set_data('x', self.bin_edges) def _hist_changed(self): self.plot._components[1].data.set_data('y', self.hist)
class EXDesignReader(HasTraits): '''Read the data from the directory The design is described in semicolon-separated csv file providing the information about design parameters. Each file has the name n.txt ''' #-------------------------------------------------------------------- # Specification of the design - factor list, relative paths, etc #-------------------------------------------------------------------- open_exdesign = Button() def _open_exdesign_fired(self): file_name = open_file(filter=['*.eds'], extensions=[FileInfo(), TextInfo()]) if file_name != '': self.exdesign_spec_file = file_name exdesign_spec_file = File def _exdesign_spec_file_changed(self): f = file(self.exdesign_spec_file) str = f.read() self.exdesign_spec = eval('ExDesignSpec( %s )' % str) exdesign_spec = Instance(ExDesignSpec) def _exdesign_spec_default(self): return ExDesignSpec() @on_trait_change('exdesign_spec') def _reset_design_file(self): dir = os.path.dirname(self.exdesign_spec_file) exdesign_file = self.exdesign_spec.design_file self.design_file = os.path.join(dir, exdesign_file) exdesign_table_columns = Property(List, depends_on='exdesign_spec+') @cached_property def _get_exdesign_table_columns(self): return [ ObjectColumn(name=ps[2], editable=False, width=0.15) for ps in self.exdesign_spec.factors ] #-------------------------------------------------------------------- # file containing the association between the factor combinations # and data files having the data #-------------------------------------------------------------------- design_file = File def _design_file_changed(self): self.exdesign = self._read_exdesign() exdesign = List(ExRun) def _exdesign_default(self): return self._read_exdesign() def _read_exdesign(self): ''' Read the experiment design. ''' if exists(self.design_file): reader = csv.reader(open(self.design_file, 'r'), delimiter=';') data_dir = os.path.join(os.path.dirname(self.design_file), self.exdesign_spec.data_dir) return [ExRun(self, row, data_dir=data_dir) for row in reader] else: return [] response_array = Property(Array(float), depends_on='exdesign') @cached_property def _get_response_array(self): '''Get the specified response values ''' return array([[ e.max_stress, e.strain_at_max_stress, e.max_stiffness, e.strain_at_max_stiffness ] for e in self.exdesign], dtype='float_') selected_exrun = Instance(ExRun) def _selected_exrun_default(self): if len(self.exdesign) > 0: return self.exdesign[0] else: return None last_exrun = Instance(ExRun) selected_exruns = List(ExRun) #------------------------------------------------------------------ # Array plotting #------------------------------------------------------------------- # List of arrays to be plotted data = Instance(AbstractPlotData) def _data_default(self): return ArrayPlotData(x=array([]), y=array([])) @on_trait_change('selected_exruns') def _rest_last_exrun(self): if len(self.selected_exruns) > 0: self.last_exrun = self.selected_exruns[-1] @on_trait_change('selected_exruns') def _reset_data(self): ''' ''' runs, xlabels, ylabels, xlabels_afit, ylabels_afit, xlins, ylins = self._generate_data_labels( ) for name in list(self.plot.plots.keys()): self.plot.delplot(name) for idx, exrun in enumerate(self.selected_exruns): if xlabels[idx] not in self.plot.datasources: self.plot.datasources[xlabels[idx]] = ArrayDataSource( exrun.xdata, sort_order='none') if ylabels[idx] not in self.plot.datasources: self.plot.datasources[ylabels[idx]] = ArrayDataSource( exrun.ydata, sort_order='none') if xlabels_afit[idx] not in self.plot.datasources: self.plot.datasources[xlabels_afit[idx]] = ArrayDataSource( exrun.xdata_asc_fit, sort_order='none') if ylabels_afit[idx] not in self.plot.datasources: self.plot.datasources[ylabels_afit[idx]] = ArrayDataSource( exrun.ydata_asc_fit, sort_order='none') xlin, ylin = exrun.get_linear_data() if xlins[idx] not in self.plot.datasources: self.plot.datasources[xlins[idx]] = ArrayDataSource( xlin, sort_order='none') if ylins[idx] not in self.plot.datasources: self.plot.datasources[ylins[idx]] = ArrayDataSource( ylin, sort_order='none') for run, xlabel, ylabel, xlabel_afit, ylabel_afit, xlin, ylin in zip( runs, xlabels, ylabels, xlabels_afit, ylabels_afit, xlins, ylins): self.plot.plot((xlabel, ylabel), color='brown') self.plot.plot((xlabel_afit, ylabel_afit), color='blue') self.plot.plot((xlin, ylin), color='red') def _generate_data_labels(self): ''' Generate the labels consisting of the axis and run-number. ''' return ( [e.std_num for e in self.selected_exruns], ['x-%d' % e.std_num for e in self.selected_exruns], ['y-%d' % e.std_num for e in self.selected_exruns], ['x-%d-fitted' % e.std_num for e in self.selected_exruns], ['y-%d-fitted' % e.std_num for e in self.selected_exruns], ['x-%d-lin' % e.std_num for e in self.selected_exruns], ['y-%d-lin' % e.std_num for e in self.selected_exruns], ) plot = Instance(Plot) def _plot_default(self): p = Plot() p.tools.append(PanTool(p)) p.overlays.append(ZoomTool(p)) return p view_traits = View(HSplit( VGroup( Item('open_exdesign', style='simple'), Item('exdesign', editor=exrun_table_editor, show_label=False, style='custom')), VGroup( Item('last_exrun@', show_label=False), Item('plot', editor=ComponentEditor(), show_label=False, resizable=True), ), ), resizable=True, buttons=[OKButton, CancelButton], height=1., width=1.)
format_str="%5.3f", tooltip= "Pulse Response Zero Forcing approximation error.", style="readonly", ), label="Tuning Options", show_border=True, ), springy=False, ), Item( label= "Note: Only CTLE boost will be optimized; please, set peak frequency, bandwidth, and mode appropriately.", ), Item("plot_h_tune", editor=ComponentEditor(), show_label=False, springy=True), HGroup( Item( "btn_rst_eq", show_label=False, tooltip="Reset all values to those on the 'Config.' tab."), Item("btn_save_eq", show_label=False, tooltip="Store all values to 'Config.' tab."), Item("btn_opt_tx", show_label=False, tooltip="Run Tx tap weight optimization."), Item("btn_opt_rx", show_label=False,
class CursorTest(HasTraits): plot = Instance(HPlotContainer) cursor1 = Instance(BaseCursorTool) cursor2 = Instance(BaseCursorTool) cursor1pos = DelegatesTo('cursor1', prefix='current_position') cursor2pos = DelegatesTo('cursor2', prefix='current_position') def __init__(self): #The delegates views don't work unless we caller the superclass __init__ super(CursorTest, self).__init__() container = HPlotContainer(padding=0, spacing=20) self.plot = container #a subcontainer for the first plot. #I'm not sure why this is required. Without it, the layout doesn't work right. subcontainer = OverlayPlotContainer(padding=40) container.add(subcontainer) #make some data index = numpy.linspace(-10,10,512) value = numpy.sin(index) #create a LinePlot instance and add it to the subcontainer line = create_line_plot([index, value], add_grid=True, add_axis=True, index_sort='ascending', orientation = 'h') subcontainer.add(line) #here's our first cursor. csr = CursorTool(line, drag_button="left", color='blue') self.cursor1 = csr #and set it's initial position (in data-space units) csr.current_position = 0.0, 0.0 #this is a rendered component so it goes in the overlays list line.overlays.append(csr) #some other standard tools line.tools.append(PanTool(line, drag_button="right")) line.overlays.append(ZoomTool(line)) #make some 2D data for a colourmap plot xy_range = (-5, 5) x = numpy.linspace(xy_range[0], xy_range[1] ,100) y = numpy.linspace(xy_range[0], xy_range[1] ,100) X,Y = numpy.meshgrid(x, y) Z = numpy.sin(X)*numpy.arctan2(Y,X) #easiest way to get a CMapImagePlot is to use the Plot class ds = ArrayPlotData() ds.set_data('img', Z) img = Plot(ds, padding=40) cmapImgPlot = img.img_plot("img", xbounds = xy_range, ybounds = xy_range, colormap = viridis)[0] container.add(img) #now make another cursor csr2 = CursorTool(cmapImgPlot, drag_button='left', color='white', line_width=2.0 ) self.cursor2 = csr2 csr2.current_position = 1.0, 1.5 cmapImgPlot.overlays.append(csr2) #add some standard tools. Note, I'm assigning the PanTool to the #right mouse-button to avoid conflicting with the cursors cmapImgPlot.tools.append(PanTool(cmapImgPlot, drag_button="right")) cmapImgPlot.overlays.append(ZoomTool(cmapImgPlot)) traits_view = View(VGroup( HGroup(Item('plot', editor=ComponentEditor(), resizable=True, springy=True, show_label=False), springy=True), HGroup(Item('cursor1pos', width=300), Item('cursor2pos', width=300))), title="Cursor Tool Demo", resizable=True, width=800, height=420)
class WorldMapPlot(HasTraits): ### Public Traits ########################################################## # The plot which will be displayed plot = Instance(Plot) # The URL which points to the world map image to be downloaded image_url = Str( "http://eoimages.gsfc.nasa.gov/ve//2433/land_shallow_topo_2048.jpg") ### Private Traits ######################################################### # The path to where the image exists on the filesystem image_path = Str() # The view traits_view = View(Item('plot', editor=ComponentEditor(), width=800, height=400, show_label=False), resizable=True) #--------------------------------------------------------------------------- # Public interface #--------------------------------------------------------------------------- def __init__(self, **kw): super(WorldMapPlot, self).__init__(**kw) self._download_map_image() image = ImageData.fromfile(self.image_path) # For now, the locations are hardcoded, though this can be changed # eassily to take command line args, read from a file, or by other # means austin_loc = (30.16, -97.44) locations_x = numpy.array([austin_loc[1]]) locations_y = numpy.array([austin_loc[0]]) # transform each of the locations to the image data space, including # moving the origin from bottom left to top left locations_x = (locations_x + 180) * image.data.shape[1] / 360 locations_y = (locations_y * -1 + 90) * image.data.shape[0] / 180 # Create the plott data, adding the image and the locations plot_data = ArrayPlotData() plot_data.set_data("imagedata", image._data) plot_data.set_data("locations_x", locations_x) plot_data.set_data("locations_y", locations_y) # Create the plot with the origin as top left, which matches # how the image data is aligned self.plot = Plot(plot_data, default_origin="top left") self.plot.img_plot('imagedata') # Plot the locations as a scatter plot to be overlayed on top # of the map loc_plot = self.plot.plot(('locations_x', 'locations_y'), type='scatter', size=3, color='yellow', marker='dot')[0] loc_plot.x_mapper.range.high = image.data.shape[1] loc_plot.x_mapper.range.low = 0 loc_plot.y_mapper.range.high = image.data.shape[0] loc_plot.y_mapper.range.low = -0 # set up any tools, in this case just the zoom tool zoom = ZoomTool(component=self.plot, tool_mode="box", always_on=False) self.plot.overlays.append(zoom) #--------------------------------------------------------------------------- # Protected interface #--------------------------------------------------------------------------- def _download_map_image(self): """ Downloads a map from the image_url attribute. This is done primarily to keep the redistributable Chaco package as small as possible """ example_dir = os.path.dirname(__file__) self.image_path = os.path.join(example_dir, 'data', os.path.split(self.image_url)[1]) if not os.path.exists(self.image_path): print "Downloading map image" urllib.urlretrieve(self.image_url, self.image_path)
class ImagePlotInspector(traits.HasTraits): #Traits view definitions: plotGroup = traitsui.Group( traitsui.Item('container', editor=ComponentEditor(size=(800, 600)), show_label=False)) #--------------------------------------------------------------------------- # Private Traits #--------------------------------------------------------------------------- _image_index = traits.Instance(chaco.GridDataSource) _image_value = traits.Instance(chaco.ImageData) _cmap = traits.Trait(colormaps.jet, traits.Callable) def create_plot(self): # Create the mapper, etc self._image_index = chaco.GridDataSource(scipy.array([]), scipy.array([]), sort_order=("ascending", "ascending")) image_index_range = chaco.DataRange2D(self._image_index) self._image_index.on_trait_change(self._metadata_changed, "metadata_changed") self._image_value = chaco.ImageData(data=scipy.array([]), value_depth=1) image_value_range = chaco.DataRange1D(self._image_value) # Create the contour plots #self.polyplot = ContourPolyPlot(index=self._image_index, self.polyplot = chaco.CMapImagePlot( index=self._image_index, value=self._image_value, index_mapper=chaco.GridMapper(range=image_index_range), color_mapper=self._cmap(image_value_range)) # Add a left axis to the plot left = chaco.PlotAxis(orientation='left', title="y", mapper=self.polyplot.index_mapper._ymapper, component=self.polyplot) self.polyplot.overlays.append(left) # Add a bottom axis to the plot bottom = chaco.PlotAxis(orientation='bottom', title="x", mapper=self.polyplot.index_mapper._xmapper, component=self.polyplot) self.polyplot.overlays.append(bottom) # Add some tools to the plot self.polyplot.tools.append( tools.PanTool(self.polyplot, constrain_key="shift", drag_button="middle")) self.polyplot.overlays.append( tools.ZoomTool(component=self.polyplot, tool_mode="box", always_on=False)) self.lineInspectorX = clickableLineInspector.ClickableLineInspector( component=self.polyplot, axis='index_x', inspect_mode="indexed", write_metadata=True, is_listener=False, color="white") self.lineInspectorY = clickableLineInspector.ClickableLineInspector( component=self.polyplot, axis='index_y', inspect_mode="indexed", write_metadata=True, color="white", is_listener=False) self.polyplot.overlays.append(self.lineInspectorX) self.polyplot.overlays.append(self.lineInspectorY) # self.boxSelection2D = plotObjects.boxSelection2D.BoxSelection2D(component=self.polyplot) # self.polyplot.overlays.append(self.boxSelection2D) # Add these two plots to one container self.centralContainer = chaco.OverlayPlotContainer(padding=0, use_backbuffer=True, unified_draw=True) self.centralContainer.add(self.polyplot) # Create a colorbar cbar_index_mapper = chaco.LinearMapper(range=image_value_range) self.colorbar = chaco.ColorBar( index_mapper=cbar_index_mapper, plot=self.polyplot, padding_top=self.polyplot.padding_top, padding_bottom=self.polyplot.padding_bottom, padding_right=40, resizable='v', width=30) self.plotData = chaco.ArrayPlotData( line_indexHorizontal=scipy.array([]), line_valueHorizontal=scipy.array([]), scatter_indexHorizontal=scipy.array([]), scatter_valueHorizontal=scipy.array([]), scatter_colorHorizontal=scipy.array([]), fitLine_indexHorizontal=scipy.array([]), fitLine_valueHorizontal=scipy.array([])) self.crossPlotHorizontal = chaco.Plot(self.plotData, resizable="h") self.crossPlotHorizontal.height = 100 self.crossPlotHorizontal.padding = 20 self.crossPlotHorizontal.plot( ("line_indexHorizontal", "line_valueHorizontal"), line_style="dot") self.crossPlotHorizontal.plot( ("scatter_indexHorizontal", "scatter_valueHorizontal", "scatter_colorHorizontal"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=4) self.crossPlotHorizontal.index_range = self.polyplot.index_range.x_range self.plotData.set_data("line_indexVertical", scipy.array([])) self.plotData.set_data("line_valueVertical", scipy.array([])) self.plotData.set_data("scatter_indexVertical", scipy.array([])) self.plotData.set_data("scatter_valueVertical", scipy.array([])) self.plotData.set_data("scatter_colorVertical", scipy.array([])) self.plotData.set_data("fitLine_indexVertical", scipy.array([])) self.plotData.set_data("fitLine_valueVertical", scipy.array([])) self.crossPlotVertical = chaco.Plot(self.plotData, width=140, orientation="v", resizable="v", padding=20, padding_bottom=160) self.crossPlotVertical.plot( ("line_indexVertical", "line_valueVertical"), line_style="dot") self.crossPlotVertical.plot( ("scatter_indexVertical", "scatter_valueVertical", "scatter_colorVertical"), type="cmap_scatter", name="dot", color_mapper=self._cmap(image_value_range), marker="circle", marker_size=4) self.crossPlotVertical.index_range = self.polyplot.index_range.y_range # Create a container and add components self.container = chaco.HPlotContainer(padding=40, fill_padding=True, bgcolor="white", use_backbuffer=False) inner_cont = chaco.VPlotContainer(padding=40, use_backbuffer=True) inner_cont.add(self.crossPlotHorizontal) inner_cont.add(self.centralContainer) self.container.add(self.colorbar) self.container.add(inner_cont) self.container.add(self.crossPlotVertical) def update(self, indexData, imageData): logger.info("updating plot") if self.autoRangeColor: self.colorbar.index_mapper.range.low = model.minZ self.colorbar.index_mapper.range.high = model.maxZ self._image_index.set_data(model.xs, model.ys) self._image_value.data = model.zs self.plotData.set_data("line_indexHorizontal", model.xs) self.plotData.set_data("line_indexVertical", model.ys) self.updatePlotLimits() self._image_index.metadata_changed = True self.container.invalidate_draw() self.container.request_redraw() def _metadata_changed(self, old, new): """ This function takes out a cross section from the image data, based on the line inspector selections, and updates the line and scatter plots.""" if self.horizontalAutoRange: self.crossPlotHorizontal.value_range.low = self.model.minZ self.crossPlotHorizontal.value_range.high = self.model.maxZ if self.verticalAutoRange: self.crossPlotVertical.value_range.low = self.model.minZ self.crossPlotVertical.value_range.high = self.model.maxZ if self._image_index.metadata.has_key("selections"): selections = self._image_index.metadata["selections"] if not selections: #selections is empty list return #don't need to do update lines as no mouse over screen. This happens at beginning of script x_ndx, y_ndx = selections if y_ndx and x_ndx: self.plotData.set_data("line_valueHorizontal", self._image_value.data[y_ndx, :]) self.plotData.set_data("line_valueVertical", self._image_value.data[:, x_ndx]) xdata, ydata = self._image_index.get_data() xdata, ydata = xdata.get_data(), ydata.get_data() self.plotData.set_data("scatter_indexHorizontal", scipy.array([xdata[x_ndx]])) self.plotData.set_data("scatter_indexVertical", scipy.array([ydata[y_ndx]])) self.plotData.set_data( "scatter_valueHorizontal", scipy.array([self._image_value.data[y_ndx, x_ndx]])) self.plotData.set_data( "scatter_valueVertical", scipy.array([self._image_value.data[y_ndx, x_ndx]])) self.plotData.set_data( "scatter_colorHorizontal", scipy.array([self._image_value.data[y_ndx, x_ndx]])) self.plotData.set_data( "scatter_colorVertical", scipy.array([self._image_value.data[y_ndx, x_ndx]])) if self.drawFitBool: self.plotData.set_data("fitLine_valueHorizontal", self._fit_value.data[y_ndx, :]) self.plotData.set_data("fitLine_valueVertical", self._fit_value.data[:, x_ndx]) else: self.plotData.set_data("scatter_valueHorizontal", scipy.array([])) self.plotData.set_data("scatter_valueVertical", scipy.array([])) self.plotData.set_data("line_valueHorizontal", scipy.array([])) self.plotData.set_data("line_valueVertical", scipy.array([])) self.plotData.set_data("fitLine_valueHorizontal", scipy.array([])) self.plotData.set_data("fitLine_valueVertical", scipy.array([])) def _colormap_changed(self): self._cmap = colormaps.color_map_name_dict[self.colormap] if hasattr(self, "polyplot"): value_range = self.polyplot.color_mapper.range self.polyplot.color_mapper = self._cmap(value_range) value_range = self.crossPlotHorizontal.color_mapper.range self.crossPlotHorizontal.color_mapper = self._cmap(value_range) # FIXME: change when we decide how best to update plots using # the shared colormap in plot object self.crossPlotHorizontal.plots["dot"][0].color_mapper = self._cmap( value_range) self.crossPlotVertical.plots["dot"][0].color_mapper = self._cmap( value_range) self.container.request_redraw() def _colorMapRangeLow_changed(self): self.colorbar.index_mapper.range.low = self.colorMapRangeLow def _colorMapRangeHigh_changed(self): self.colorbar.index_mapper.range.high = self.colorMapRangeHigh def _horizontalLowerLimit_changed(self): self.crossPlotHorizontal.value_range.low = self.horizontalLowerLimit def _horizontalUpperLimit_changed(self): self.crossPlotHorizontal.value_range.high = self.horizontalUpperLimit def _verticalLowerLimit_changed(self): self.crossPlotVertical.value_range.low = self.verticalLowerLimit def _verticalUpperLimit_changed(self): self.crossPlotVertical.value_range.high = self.verticalUpperLimit def _autoRange_changed(self): if self.autoRange: self.colorbar.index_mapper.range.low = self.minz self.colorbar.index_mapper.range.high = self.maxz def _num_levels_changed(self): if self.num_levels > 3: self.polyplot.levels = self.num_levels self.lineplot.levels = self.num_levels def _colorMapRangeLow_default(self): logger.debug("setting color map rangle low default") return self.model.minZ def _colorMapRangeHigh_default(self): return self.model.maxZ def _horizontalLowerLimit_default(self): return self.model.minZ def _horizontalUpperLimit_default(self): return self.model.maxZ def _verticalLowerLimit_default(self): return self.model.minZ def _verticalUpperLimit_default(self): return self.model.maxZ