class LinePlot(HasTraits): plot = Instance(Plot) data = Instance(ArrayPlotData) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="Chaco Plot") def __init__(self, **traits): super(LinePlot, self).__init__(**traits) x = np.linspace(-14, 14, 100) y = np.sin(x) * x**3 data = ArrayPlotData(x=x, y=y) plot = Plot(data) plot.plot(("x", "y"), type="line", color="blue") plot.title = "sin(x) * x^3" plot.tools.append(PanTool(plot)) plot.tools.append( DragZoom(plot, drag_button="right", maintain_aspect_ratio=False)) plot.overlays.append(ZoomTool(plot)) # plot.overlays.append(ZoomTool(plot, tool_mode="range", axis = "index", # always_on=True, always_on_modifier="control")) self.plot = plot self.data = data
class ScatterPlotTraits(HasTraits): plot = Instance(Plot) data = Instance(ArrayPlotData) color = Color("blue") marker = marker_trait traits_view = View(Group(Item('color', label="Color"), Item('marker', label="Marker"), Item('object.line.marker_size', label="Size"), Item('plot', editor=ComponentEditor(), show_label=False), orientation="vertical"), width=800, height=600, resizable=True, title="Chaco Plot") def __init__(self, **traits): super(ScatterPlotTraits, self).__init__(**traits) x = np.linspace(-14, 14, 100) y = np.sin(x) * x**3 data = ArrayPlotData(x=x, y=y) plot = Plot(data) self.line = plot.plot(("x", "y"), type="scatter", color="blue")[0] self.plot = plot self.data = data def _color_changed(self): self.line.color = self.color def _marker_changed(self): self.line.marker = self.marker
class ProbePlot(HasTraits): def __init__(self): super(Probe, self).__init__() x = linspace(0, self.N, self.N / self.d) y = linspace(0, self.N, self.N / self.d) xgrid, ygrid = meshgrid(x[1:], y[1:]) z = exp(-(xgrid * xgrid + ygrid * ygrid) / 10000) plotdata = ArrayPlotData(imagedata=z) plot = Plot(plotdata) self.renderer = plot.img_plot("imagedata", xbounds=x, ybounds=y, colormap=bone) #self.renderer = plot.plot(("x", "y"), type="scatter", color="blue")[0] self.plot = plot traits_view = View(VGroup( HGroup( Item('HT', label="High Tension, kV", help='The microscope accelerating voltage'), spring, Item('wl', label="Wavelength, nm", style='readonly')), HGroup(spring, Item('alpha', label="Conv. Angle")), HGroup(VGroup(Item('noms', label="Nomenclature")), Item('notations[self.noms]', label='Labels')), HGroup(Item('plot', editor=ComponentEditor(), show_label=False))), width=800, height=600, resizable=True, title="Chaco Plot")
class MutiLinePlot(HasTraits): plot = Instance(Plot) data = Instance(ArrayPlotData) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="Chaco Plot") def __init__(self, **traits): super(MutiLinePlot, self).__init__(**traits) x = np.linspace(-14, 14, 100) y1 = np.sin(x) * x**3 y2 = np.cos(x) * x**3 data = ArrayPlotData(x=x, y1=y1, y2=y2) plot = Plot(data) plot.plot(("x", "y1"), type="line", color="blue", name="sin(x) * x**3") plot.plot(("x", "y2"), type="line", color="red", name="cos(x) * x**3") plot.plot(("x", "y2"), type="scatter", color="red", marker="circle", marker_size=2, name="cos(x) * x**3 points") plot.title = "Multiple Curves" plot.legend.visible = True self.plot = plot self.data = data
class CircleSelectionDemo(HasTraits): plot = Instance(Plot) data = Instance(ArrayPlotData) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="Circle Selection Plot") def __init__(self, **traits): super(CircleSelectionDemo, self).__init__(**traits) x = np.random.random(100) * 2 y = np.random.random(100) data = ArrayPlotData(x=x, y=y) plot = Plot(data) scatter = plot.plot(("x", "y"), type="scatter", color="blue")[0] scatter.tools.append(CircleSelection(scatter)) scatter.overlays.append( ScatterInspectorOverlay(scatter, selection_color="red", selection_marker="circle", selection_outline_color="black", selection_marker_size=6)) scatter.overlays.append(CircleSelectionOverlay(scatter)) self.plot = plot self.data = data
class LinePlot(HasTraits): plot = Instance(Plot) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="Chaco Plot") def __init__(self): super(LinePlot, self).__init__() x = linspace(-14, 14, 100) y1 = sin(x) * x**3 y2 = cos(x) * x**3 plotdata = ArrayPlotData(x=x, y1=y1, y2=y2) plot = Plot(plotdata) plot.plot(("x", "y1"), type="line", color="blue", name="sin(x) * x**3") plot.plot(("x", "y2"), type="line", color="red", name="cos(x) * x**3") plot.plot(("x", "y2"), type="scatter", color="red", marker="circle", marker_size=2, name="cos(x) * x**3 points") plot.title = "Multiple Curves" self.plot = plot legend = Legend(padding=10, align="ur") legend.plots = plot.plots plot.overlays.append(legend)
class HistDemo(HasTraits): plot = Instance(Plot) timer = Instance(Timer) need_update = Bool(False) view = View(Item("plot", editor=ComponentEditor(), show_label=False), resizable=True, width=500, height=250, title="Hist Demo") def __init__(self, **traits): super(HistDemo, self).__init__(**traits) img = cv.imread("lena.jpg") gray_img = cv.Mat() cv.cvtColor(img, gray_img, cv.CV_BGR2GRAY) self.img = gray_img self.img2 = self.img.clone() result = cv.MatND() r = cv.vector_float32([0, 256]) ranges = cv.vector_vector_float32([r, r]) cv.calcHist(cv.vector_Mat([self.img]), channels=cv.vector_int([0, 1]), mask=cv.Mat(), hist=result, histSize=cv.vector_int([256]), ranges=ranges) data = ArrayPlotData(x=np.arange(0, len(result[:])), y=result[:]) self.plot = Plot(data, padding=10) line = self.plot.plot(("x", "y"))[0] self.select_tool = RangeSelection(line, left_button_selects=True) line.tools.append(self.select_tool) self.select_tool.on_trait_change(self._selection_changed, "selection") line.overlays.append(RangeSelectionOverlay(component=line)) cv.imshow("Hist Demo", self.img) self.timer = Timer(50, self.on_timer) def _selection_changed(self): if self.select_tool.selection != None: self.need_update = True def on_timer(self): if self.need_update: x0, x1 = self.select_tool.selection self.img2[:] = self.img[:] np.clip(self.img2[:], x0, x1, out=self.img2[:]) self.img2[:] -= x0 self.img2[:] *= 256.0 / (x1 - x0) cv.imshow("Hist Demo", self.img2) self.need_update = False
class IMUGloveDisplay(HasTraits): plot = Instance(HPlotContainer) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=1000, height=600, resizable=True, title="IMU Glove Display") def __init__(self): super(IMUGloveDisplay, self).__init__() x = linspace(-14, 14, 100) y = sin(x) * x**3 plotdata = ArrayPlotData(x=x, y=y) scatter = Plot(plotdata) scatter.plot(("x", "y"), type="scatter", color="blue") line = Plot(plotdata) line.plot(("x", "y"), type="line", color="blue") container = HPlotContainer(scatter, line) #scatter.title = "sin(x) * x^3" #line.title = 'line plot' self.plot = container self.InitGlove() def InitGlove(self): self.api = GloveAPI() self.api.initHardware() self.api.debug(False) self.api.configimu() def ReadData(self, numToRead): ''' Start streaming data ''' self.api.stream(numToRead) self.api.clearIMUPacketEngine() keys = [ 'sentinal', 'footer', 'temp', 'gx', 'gy', 'gz', 'ax', 'ay', 'az', 'sentinal' ] #keys = ['gx','gy','gz','ax','ay','az'] packets = [] t = time.time() for x in range(0, numToRead): p = self.api.getIMUPacket() if p: ''' Update the data in the plot.. ''' showPacket(p, keys) else: self.api.configimu() self.api.stream(numToRead - x) tdiff = time.time() - t print("Total time:%6.6f Time per Packet:%6.6f" % (tdiff, tdiff / x))
class ComponentViewer(HasTraits): """ A viewer of components for testing purposes """ # The component being viewed component = Instance(Component) # The canvas to which the component is added canvas = Instance(Canvas) # A view into a subsection of the canvas viewport = Instance(Viewport) # Default view traits_view = View(HSplit( Group(Item("viewport", editor=ComponentEditor(), show_label=False)), Group(Item(name="component", style="custom", show_label=False), scrollable=True)), resizable=True, id="canvas_viewer", width=.6, height=.4, title="Viewer") def _canvas_default(self): """ Trait initialiser """ canvas = Canvas(draw_axes=True, bgcolor="honeydew") return canvas def _viewport_default(self): """ Trait initialiser """ viewport = Viewport(component=self.canvas, enable_zoom=True) viewport.tools.append(ViewportPanTool(viewport)) return viewport def _component_changed(self, old, new): """ Handles the component being changed. """ canvas = self.canvas if old is not None: canvas.remove(old) if new is not None: canvas.add(new) def _anytrait_changed_for_component(self, new): """ Handles redrawing of the canvas. """ self.canvas.request_redraw()
class LassoDemoPlot(HasTraits): plot = Instance(HPlotContainer) data = Instance(ArrayPlotData) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=600, height=320, resizable=True, title="Lasso Tool Demo") def __init__(self, **traits): super(LassoDemoPlot, self).__init__(**traits) x = np.random.random(N) y = np.random.random(N) x2 = np.array([]) y2 = np.array([]) data = ArrayPlotData(x=x, y=y, x2=x2, y2=y2) plot1 = Plot(data, padding=10) scatter_plot1 = plot1.plot(("x", "y"), type="scatter", marker="circle", color="blue")[0] self.lasso = LassoSelection(scatter_plot1, incremental_select=True, selection_datasource=scatter_plot1.index) self.lasso.on_trait_change(self._selection_changed, 'selection_changed') scatter_plot1.tools.append(self.lasso) scatter_plot1.overlays.append( LassoOverlay(scatter_plot1, lasso_selection=self.lasso)) plot2 = Plot(data, padding=10) plot2.index_range = plot1.index_range plot2.value_range = plot1.value_range plot2.plot(("x2", "y2"), type="scatter", marker="circle", color="red") self.plot = HPlotContainer(plot1, plot2) self.plot2 = plot2 self.data = data def _selection_changed(self): index = np.array(self.lasso.selection_datasource.metadata["selection"], dtype=np.bool) self.data["x2"] = self.data["x"][index] self.data["y2"] = self.data["y"][index]
class Plot_i(HasTraits): plot = Instance(Plot) color = ColorTrait('blue') marker = marker_trait marker_size = Int(4) line_width = Int(4) traits_view = View(Group(Tabbed(Group( \ Group(Item('color', label="Color"), \ Item('marker', label="Marker"), \ orientation = 'vertical'), \ Group( \ Item('marker_size', label= "Size"), \ Item('line_width', label = 'Linewidth'), \ orientation = 'vertical'), \ dock = 'tab', orientation = 'vertical')), \ Item('plot', editor=ComponentEditor(), show_label=False), orientation = 'horizontal'), \ width=800, height=600, resizable=True, title="Chaco Plot") def __init__(self,X,Y): super(Plot_i, self).__init__() self.load_data(X,Y) self.start() def load_data(self,X,Y) : self.X = X self.Y = Y plotdata = ArrayPlotData(x = X, y = Y) plot = Plot(plotdata) self.renderer_line = plot.plot(('x','y'),type = 'line', color = "blue")[0] self.renderer_scat = plot.plot(('x','y'),type = 'scatter', color = "blue")[0] self.plot = plot def start(self): self.configure_traits() def _color_changed(self): self.renderer_line.color = self.color self.renderer_scat.color = self.color def _marker_changed(self): self.renderer_scat.marker = self.marker def _marker_size_changed(self): self.renderer_scat.marker_size = self.marker_size def _line_width_changed(self): self.renderer_line.line_width = self.line_width
class LinePlot(HasTraits): plot = Instance(Plot) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="QTLab Analysis Plot") def __init__(self, title, xtitle, x, ytitle, y, type="line", color="blue"): super(LinePlot, self).__init__() plotdata = ArrayPlotData(x=x, y=y) self.plotdata = plotdata plot = Plot(self.plotdata) plot.plot(('x', 'y'), type=type, color=color) plot.title = title plot.x_axis.title = xtitle plot.y_axis.title = ytitle self.plot = plot self._hid = 0 self._colors = ['blue', 'red', 'black', 'green', 'magenta', 'yellow'] # Add some tools self.plot.tools.append(PanTool(self.plot, constrain_key="shift")) self.plot.overlays.append( ZoomTool(component=self.plot, tool_mode="box", always_on=False)) def update_plot(self, x, y): ''' Update plot ''' self.plotdata.set_data('x', x) self.plotdata.set_data('y', y) self.plot.data = self.plotdata self.plot.request_redraw() def plot_hold_on(self, x, y, type="line"): ''' Plot if hold on ''' self._hid = self._hid + 1 self.plotdata.set_data('x' + str(self._hid), x) self.plotdata.set_data('y' + str(self._hid), y) self.plot.plot(('x' + str(self._hid), 'y' + str(self._hid)), type=type, color=self._colors[self._hid % len(self._colors)]) self.plot.request_redraw()
class LinePlot(HasTraits): plot = Instance(Plot) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="Chaco Plot") def __init__(self): super(LinePlot, self).__init__() x = linspace(-14, 14, 100) y = sin(x) * x**3 plotdata = ArrayPlotData(x=x, y=y) plot = Plot(plotdata) plot.plot(("x", "y"), type="line", color="blue") plot.title = "sin(x) * x^3" self.plot = plot
class ImagePlot(HasTraits): plot = Instance(Plot) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="Chaco Plot") def __init__(self): super(ImagePlot, self).__init__() x = np.linspace(0, 10, 50) y = np.linspace(0, 5, 50) xgrid, ygrid = np.meshgrid(x, y) z = np.exp(-(xgrid * xgrid + ygrid * ygrid) / 100) plotdata = ArrayPlotData(imagedata=z) plot = Plot(plotdata) plot.img_plot("imagedata", xbounds=x, ybounds=y, colormap=jet) self.plot = plot
class ContainerExample(HasTraits): plot = Instance(HPlotContainer) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=1000, height=600, resizable=True, title="Chaco Plot") def __init__(self): super(ContainerExample, self).__init__() x = linspace(-14, 14, 100) y = sin(x) * x**3 plotdata = ArrayPlotData(x=x, y=y) scatter = Plot(plotdata) scatter.plot(("x", "y"), type="scatter", color="blue") line = Plot(plotdata) line.plot(("x", "y"), type="line", color="blue") container = HPlotContainer(scatter, line) self.plot = container
class ContainerExample(HasTraits): plot = Instance(VPlotContainer) data = Instance(ArrayPlotData) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=1000, height=600, resizable=True, title="Chaco Plot") def __init__(self, **traits): super(ContainerExample, self).__init__(**traits) x = np.linspace(-14, 14, 100) y = np.sin(x) * x**3 / 1000 data = ArrayPlotData(x=x, y=y) p1 = Plot(data, padding=30) p1.plot(("x", "y"), type="scatter", color="blue") p1.plot(("x", "y"), type="line", color="blue") p2 = Plot(data, padding=30) p2.plot(("x", "y"), type="line", color="blue") p2.set(bounds=[200, 100], position=[70, 150], bgcolor=(0.9, 0.9, 0.9), unified_draw=True, resizable="") p3 = Plot(data, padding=30) p3.plot(("x", "y"), type="line", color="blue", line_width=2.0) p4 = Plot(data, padding=30) p4.plot(("x", "y"), type="scatter", color="red", marker="circle") c1 = OverlayPlotContainer(p1, p2) c1.fixed_preferred_size = p3.get_preferred_size() c2 = HPlotContainer(c1, p3) c3 = VPlotContainer(p4, c2) self.plot = c3
class LassoDemoPlot(HasTraits): plot = Instance(HPlotContainer) traits_view = View( Item('plot',editor=ComponentEditor(), show_label=False), width=600, height=320, resizable=True, title="Lasso Tool Demo") def __init__(self): x, y = np.ogrid[-2*np.pi:2*np.pi:256j, -2*np.pi:2*np.pi:256j] self.img_data = np.sin(x)*y #self.img_mask = np.zeros((len(x), len(y[0]), 4), dtype=np.uint8) #self.img_mask[:, :, 3] = 255 self.img_index = np.array(list((np.broadcast(y, x)))) plotdata = ArrayPlotData(img_data=self.img_data, mask_data=self.img_data) plot1 = Plot(plotdata, padding=10) img_plot = plot1.img_plot("img_data", xbounds=(np.min(x), np.max(x)), ybounds=(np.min(y), np.max(y)))[0] self.lasso = LassoSelection(img_plot) img_plot.tools.append(self.lasso) self.ll = LassoOverlay(img_plot, lasso_selection=self.lasso) img_plot.overlays.append(self.ll) self.lasso.on_trait_change(self._selection_changed, 'selection_completed') plot2 = Plot(plotdata, padding=10) plot2.img_plot("mask_data") self.plot = HPlotContainer(plot1, plot2) self.plot1 = plot1 self.plot2 = plot2 self.plotdata = plotdata def _selection_changed(self): data = np.logical_not(points_in_polygon(self.img_index, self.lasso.dataspace_points, False).astype(np.bool)) data = data.reshape((256, 256)) copy = self.img_data.copy() copy[data] = 0 self.plotdata["mask_data"] = copy self.plot2.request_redraw()
class SelectionDemo(HasTraits): plot = Instance(VPlotContainer) data = Instance(ArrayPlotData) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="范围选择演示") def __init__(self, **traits): super(SelectionDemo, self).__init__(**traits) x = np.linspace(-140, 140, 1000) y = np.sin(x) * x**3 y /= np.max(y) data = ArrayPlotData(x=x, y=y) self.plot1 = plot1 = Plot(data, padding=25) self.line1 = line1 = plot1.plot(("x", "y"), type="line")[0] self.select_tool = select_tool = RangeSelection(line1) line1.tools.append(select_tool) select_tool.on_trait_change(self._selection_changed, "selection") line1.overlays.append(RangeSelectionOverlay(component=line1)) self.plot2 = plot2 = Plot(data, padding=25) plot2.plot(("x", "y"), type="line")[0] self.plot = VPlotContainer(plot2, plot1) self.data = data def _selection_changed(self): selection = self.select_tool.selection if selection != None: self.plot2.index_range.set_bounds(*selection) else: self.plot2.index_range.reset()
class LinePlot(HasTraits): plot = Instance(Plot) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="Chaco Plot") def __init__(self): x = np.linspace(-14, 14, 100) y = np.sin(x) * x**3 y2 = np.cos(x) * x**3 plotdata = ArrayPlotData(x=x, y=y, y2=y2) plot = Plot(plotdata) plot.plot(("x", "y"), type="line", color="blue", name="sin") plot.plot(("x", "y2"), type="line", color="red", name="cos") #line.index.sort_order = "ascending" plot.title = "sin(x) * x^3" plot.legend.visible = True plot.legend.tools.append(LegendHighlighter(plot.legend)) self.plot = plot self.plotdata = plotdata
class ImagePlot(HasTraits): plot = Instance(Plot) colormap = Enum(sorted(color_map_name_dict.keys())) data = Array traits_view = View(Item('colormap'), Item('plot', editor=ComponentEditor(), show_label=False), width=600, height=400, title="Color Map") def __init__(self): # Create plot data. row = linspace(0, 1, 100) self.data = ones([10, 100]) * row plotdata = ArrayPlotData(imagedata=self.data) # Create a Plot and associate it with the PlotData plot = Plot(plotdata) # Create a line plot in the Plot plot.img_plot("imagedata", xbounds=(0, 1), colormap=color_map_name_dict[self.colormap])[0] plot.y_axis.visible = False self.plot = plot self.plot.aspect_ratio = 5 def _colormap_changed(self, new): colormap = color_map_name_dict[self.colormap] colormap = colormap(self.plot.color_mapper.range) self.plot.color_mapper = colormap self.plot.request_redraw()
class AnimationPlot(HasTraits): plot = Instance(Plot) data = Instance(ArrayPlotData) phase = Float(0) traits_view = View( Item('plot',editor=ComponentEditor(), show_label=False), width=500, height=500, resizable=True, title="Plot Animation", handler = AnimationHandler()) def __init__(self, **traits): super(AnimationPlot, self).__init__(**traits) data = ArrayPlotData(x=[0], y=[0]) plot = Plot(data) plot.plot(("x", "y"), type="line", color="blue") plot.title = "sin(x)" self.plot = plot self.data = data def on_timer(self): x = np.linspace(self.phase, self.phase+np.pi*4, 100) y = np.sin(x) self.phase += 0.02 self.data["x"] = x self.data["y"] = y
class LFapplication(HasTraits): traits_view = View(Item('LF_img', editor=ComponentEditor(), show_label=False), Item('X_angle', label='Angle in the X axis'), Item('Y_angle', label='Angle in the Y axis'), resizable=True, title="LF Image") def __init__(self, img_path): super(LFapplication, self).__init__() # # Load image data # base_path = os.path.splitext(img_path)[0] lenslet_path = base_path + '-lenslet.txt' optics_path = base_path + '-optics.txt' with open(lenslet_path, 'r') as f: tmp = eval(f.readline()) x_offset, y_offset, right_dx, right_dy, down_dx, down_dy = \ np.array(tmp, dtype=np.float32) with open(optics_path, 'r') as f: for line in f: name, val = line.strip().split() try: setattr(self, name, np.float32(val)) except: pass max_angle = math.atan(self.pitch / 2 / self.flen) # # Prepare image # im_pil = Image.open(img_path) if im_pil.mode == 'RGB': self.NCHANNELS = 3 w, h = im_pil.size im = np.zeros((h, w, 4), dtype=np.float32) im[:, :, :3] = np.array(im_pil).astype(np.float32) self.LF_dim = (ceil(h / down_dy), ceil(w / right_dx), 3) else: self.NCHANNELS = 1 im = np.array(im_pil.getdata()).reshape(im_pil.size[::-1]).astype( np.float32) h, w = im.shape self.LF_dim = (ceil(h / down_dy), ceil(w / right_dx)) x_start = x_offset - int(x_offset / right_dx) * right_dx y_start = y_offset - int(y_offset / down_dy) * down_dy x_ratio = self.flen * right_dx / self.pitch y_ratio = self.flen * down_dy / self.pitch # # Generate the cuda kernel # mod_LFview = pycuda.compiler.SourceModule( _kernel_tpl.render(newiw=self.LF_dim[1], newih=self.LF_dim[0], oldiw=w, oldih=h, x_start=x_start, y_start=y_start, x_ratio=x_ratio, y_ratio=y_ratio, x_step=right_dx, y_step=down_dy, NCHANNELS=self.NCHANNELS)) self.LFview_func = mod_LFview.get_function("LFview_kernel") self.texref = mod_LFview.get_texref("tex") # # Now generate the cuda texture # if self.NCHANNELS == 3: cuda.bind_array_to_texref( cuda.make_multichannel_2d_array(im, order="C"), self.texref) else: cuda.matrix_to_texref(im, self.texref, order="C") # # We could set the next if we wanted to address the image # in normalized coordinates ( 0 <= coordinate < 1.) # texref.set_flags(cuda.TRSF_NORMALIZED_COORDINATES) # self.texref.set_filter_mode(cuda.filter_mode.LINEAR) # # Prepare the traits # self.add_trait('X_angle', Range(-max_angle, max_angle, 0.0)) self.add_trait('Y_angle', Range(-max_angle, max_angle, 0.0)) self.plotdata = ArrayPlotData(LF_img=self.sampleLF()) self.LF_img = Plot(self.plotdata) if self.NCHANNELS == 3: self.LF_img.img_plot("LF_img") else: self.LF_img.img_plot("LF_img", colormap=gray) def sampleLF(self): # # Get the output image # output = np.zeros(self.LF_dim, dtype=np.uint8) # # Calculate the gridsize. This is entirely given by the size of our image. # blocks = (16, 16, 1) gridx = ceil(self.LF_dim[1] / blocks[1]) gridy = ceil(self.LF_dim[0] / blocks[0]) grid = (gridx, gridy) # # Call the kernel # self.LFview_func(np.float32(self.X_angle), np.float32(self.Y_angle), cuda.Out(output), texrefs=[self.texref], block=blocks, grid=grid) return output @on_trait_change('X_angle, Y_angle') def updateImge(self): self.plotdata.set_data('LF_img', self.sampleLF())
class PointSelectionDemo(HasTraits): color = Enum(Colors.keys()) green_selection = List() red_selection = List() plot = Instance(Plot) data = Instance(ArrayPlotData) traits_view = View(HSplit( Item('plot', editor=ComponentEditor(), show_label=False), VGroup( Item("color", show_label=False, style="custom"), Heading(u"绿色选择点"), Item("green_selection", show_label=False, style="readonly"), Heading(u"红色选择点"), Item("red_selection", show_label=False, style="readonly"), )), width=800, height=400, resizable=True, title=u"数据点选择演示") def __init__(self, **traits): super(PointSelectionDemo, self).__init__(**traits) x = np.random.rand(100) y = np.random.rand(100) data = ArrayPlotData(x=x, y=y) plot = Plot(data, padding=25) self.scatter = scatter = plot.plot(("x", "y"), type="scatter", marker_size=4)[0] self.select_tools = {} for i, c in enumerate(Colors.keys()): hover_name = "hover_%s" % c selection_name = "selections_%s" % c self.select_tools[c] = ScatterInspector( scatter, hover_metadata_name=hover_name, selection_metadata_name=selection_name) scatter.overlays.append( ScatterInspectorOverlay( scatter, hover_metadata_name=hover_name, selection_metadata_name=selection_name, hover_color="transparent", hover_outline_color=c, hover_marker_size=6, hover_line_width=1, selection_color=Colors[c], )) scatter.active_tool = self.select_tools[self.color] scatter.index.on_trait_change(self.selection_changed, 'metadata_changed') self.plot = plot self.data = data def _color_changed(self): self.scatter.active_tool = self.select_tools[self.color] def selection_changed(self): x = self.scatter.index.get_data() y = self.scatter.value.get_data() metadata = self.scatter.index.metadata selection = metadata.get("selections_green", []) self.green_selection = [ "%d, (%f, %f)" % (s, x[s], y[s]) for s in selection ] selection = metadata.get("selections_red", []) self.red_selection = [ "%d, (%f, %f)" % (s, x[s], y[s]) for s in selection ]
class Subgraph(BaseGraph): """ Defines a representation of a subgraph in Graphviz's dot language. """ #-------------------------------------------------------------------------- # Trait definitions: #-------------------------------------------------------------------------- # An ID is one of the following: # * Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores # ('_') or digits ([0-9]), not beginning with a digit; # * a number [-]?(.[0-9]+ | [0-9]+(.[0-9]*)? ); # * any double-quoted string ("...") possibly containing escaped # quotes (\")1; # * an HTML string (<...>). # ID = Str # # name = Alias("ID", desc="synonym for ID") # Used by InstanceEditor # # # Subgraph nodes. # nodes = List(Instance(Node)) # # # Subgraph edges. # edges = List(Instance(Edge)) # # # Subgraphs of the subgraph. # subgraphs = List(Instance("godot.subgraph.Subgraph")) # # # Separate rectangular layout regions. # clusters = List(Instance("godot.cluster.Cluster")) # Parent graph in the graph heirarchy. # parent = Instance("godot.graph.Graph") # Root graph instance. # root = Instance("godot.graph.Graph") #-------------------------------------------------------------------------- # Xdot trait definitions: #-------------------------------------------------------------------------- # For a given graph object, one will typically a draw directive before the # label directive. For example, for a node, one would first use the # commands in _draw_ followed by the commands in _ldraw_. # _draw_ = Str(desc="xdot drawing directive") # # # Label draw directive. # _ldraw_ = Str(desc="xdot label drawing directive") #-------------------------------------------------------------------------- # Dot trait definitions. #-------------------------------------------------------------------------- # Rank constraints on the nodes in a subgraph. If rank="same", all nodes # are placed on the same rank. If rank="min", all nodes are placed on the # minimum rank. If rank="source", all nodes are placed on the minimum rank, # and the only nodes on the minimum rank belong to some subgraph whose rank # attribute is "source" or "min". Analogous criteria hold for rank="max" # and rank="sink". (Note: the minimum rank is topmost or leftmost, and the # maximum rank is bottommost or rightmost.) rank = Enum("same", "min", "source", "max", "sink", desc="rank constraints on the nodes in a subgraph", graphviz=True) #-------------------------------------------------------------------------- # Views: #-------------------------------------------------------------------------- traits_view = View( VGroup( Group( Item("vp", editor=ComponentEditor(height=100), show_label=False), Item("arrange", show_label=False)), VGroup( HGroup(Item("ID"), Item("rank")), Tabbed(nodes_item, edges_item, dock="tab"), # subgraphs_notebook_group ), layout="split"), title="Subgraph", id="godot.subgraph", buttons=["OK", "Cancel", "Help"], resizable=True) #-------------------------------------------------------------------------- # "object" interface: #-------------------------------------------------------------------------- def __str__(self): """ Returns a string representation of the cluster in dot language. """ s = "subgraph" return "%s %s" % (s, super(Subgraph, self).__str__())
class DataSetBrowser(HasTraits): """ A class that allows browsing of a DataSet object with sliders to navigate through plates, images within plates, and objects within images. """ view = View(VGroup( HGroup( Item('image_plots', editor=ComponentEditor(size=(50, 50)), show_label=False), ), HGroup( Item('plots', editor=ComponentEditor(size=(250, 300)), show_label=False), ), Group( Item('object_index', editor=RangeEditor(low=1, high_name='num_objects', mode='slider')), Item('image_index', editor=RangeEditor(low=1, high_name='num_images', mode='slider')), Item('plate_index', editor=RangeEditor(low=1, high_name='num_plates', mode='slider')), ), HGroup( Item('num_internal_knots', label='Number of internal spline knots'), Item('smoothing', label='Amount of smoothing applied'))), height=700, width=800, resizable=True) # Chaco plot gfp_plot = Instance(Plot) sil_plot = Instance(Plot) image_plots = Instance(HPlotContainer) rotated_plot = Instance(Plot) plots = Instance(GridPlotContainer) #legends = Instance(VPlotContainer) # DataSet being viewed dataset = Instance(DataSet) # Plate object currently being examined current_plate = Instance(Plate) # ImageSilhouette object currently being examined current_image = Instance(ImageSilhouette) # ObjectSilhouette object currently being examined current_object = Instance(ObjectSilhouette) # Index traits that control the selected plate/image/object plate_index = Int(1) image_index = Int(1) object_index = Int(1) # Number of plates, images, and objects in the current context num_plates = Property(Int, depends_on='dataset') num_images = Property(Int, depends_on='current_plate') num_objects = Property(Int, depends_on='current_image') num_internal_knots = Range(1, 20, 3) smoothing = Range(0.0, 2.0, 0) def __init__(self, *args, **kwargs): """Construct a DataSetBrowser from the specified DataSet object.""" super(DataSetBrowser, self).__init__(*args, **kwargs) self.current_plate = self.dataset[self.plate_index - 1] self.current_image = self.current_plate[self.image_index - 1] self.current_object = self.current_image[self.object_index - 1] self.sil_plot = Plot() self._object_index_changed() ######################### Private interface ########################## def _plate_index_changed(self): """Handle the plate index changing.""" try: self.current_plate = self.dataset[self.plate_index - 1] except IndexError: self.current_plate = None self.image_index = 1 self._image_index_changed() def _image_index_changed(self): """Handle the image index slider changing.""" try: self.current_image = self.current_plate[self.image_index - 1] except IndexError: self.current_image = None self.object_index = 1 self._object_index_changed() def _object_index_changed(self): """Handle object index slider changing.""" try: self.current_object = self.current_image[self.object_index - 1] # Display sil = self.current_object.image self._update_img_plot('sil_plot', sil, 'Extracted mask') # .T to get major axis horizontal rotated = self.current_object.aligned_version.image.T self._update_img_plot('rotated_plot', rotated, 'Aligned mask') self.image_plots = HPlotContainer(self.sil_plot, self.rotated_plot, valign="top", bgcolor="transparent") self._update_spline_plot() except IndexError: self.current_object = None def _get_num_plates(self): """Return the number of plates in the currently viewed dataset.""" return len(self.dataset) def _get_num_images(self): """Return the number of images in the currently viewed plate.""" return len(self.current_plate) def _get_num_objects(self): """Return the number of objects in the currently viewed image.""" return len(self.current_image) def _update_img_plot(self, plot_name, image, title): """Update an image plot.""" plotdata = ArrayPlotData(imagedata=image) xbounds = (0, image.shape[1] - 1) ybounds = (0, image.shape[0] - 1) plot = Plot(plotdata) plot.aspect_ratio = float(xbounds[1]) / float(ybounds[1]) plot.img_plot("imagedata", colormap=bone, xbounds=xbounds, ybounds=ybounds) plot.title = title setattr(self, plot_name, plot) getattr(self, plot_name).request_redraw() def _update_spline_plot(self): """Update the spline plot.""" knots = np.mgrid[0:1:((self.num_internal_knots + 2) * 1j)][1:-1] medial_repr = self.current_object.aligned_version.medial_repr dependent_variable = np.mgrid[0:1:(medial_repr.length * 1j)] laplacian = ndimage.gaussian_laplace(medial_repr.width_curve, self.smoothing, mode='constant', cval=np.nan) m_spline = LSQUnivariateSpline(dependent_variable, medial_repr.medial_axis, knots) w_spline = LSQUnivariateSpline(dependent_variable, medial_repr.width_curve, knots) # sample at double the frequency spl_dep_var = np.mgrid[0:1:(medial_repr.length * 2j)] plots = self.plots if plots is None: # Render the plot for the first time. plotdata = ArrayPlotData( medial_x=dependent_variable, medial_y=medial_repr.medial_axis, width_x=dependent_variable, width_y=medial_repr.width_curve, medial_spline_x=spl_dep_var, medial_spline_y=m_spline(spl_dep_var), width_spline_x=spl_dep_var, width_spline_y=w_spline(spl_dep_var), laplacian_y=laplacian, ) plot = Plot(plotdata) # Width data self._width_data_renderer, = plot.plot( ("width_x", "width_y"), type="line", color="blue", name="Original width curve data") filterdata = ArrayPlotData(x=dependent_variable, laplacian=laplacian) filterplot = Plot(filterdata) self._laplacian_renderer, = filterplot.plot( ("x", "laplacian"), type="line", color="black", name="Laplacian-of-Gaussian") # Titles for plot & axes plot.title = "Width curves" plot.x_axis.title = "Normalized position on medial axis" plot.y_axis.title = "Fraction of medial axis width" # Legend mangling stuff legend = plot.legend plot.legend = None legend.set(component=None, visible=True, resizable="", auto_size=True, bounds=[250, 70], padding_top=plot.padding_top) filterlegend = filterplot.legend filterplot.legend = None filterlegend.set(component=None, visible=True, resizable="", auto_size=True, bounds=[250, 50], padding_top=filterplot.padding_top) self.plots = GridPlotContainer(plot, legend, filterplot, filterlegend, shape=(2, 2), valign="top", bgcolor="transparent") else: # Update the real width curve self._width_data_renderer.index.set_data(dependent_variable) self._width_data_renderer.value.set_data(medial_repr.width_curve) # Render the Laplacian self._laplacian_renderer.index.set_data(dependent_variable) self._laplacian_renderer.value.set_data(laplacian) def _num_internal_knots_changed(self): """Hook to update the plot when we change the number of knots.""" self._update_spline_plot() def _smoothing_changed(self): """Hook to update the plot when we change the smoothing parameter.""" self._update_spline_plot()
class SplineExplorer(traits.HasTraits): """A simple UI to adjust the parameters and view the resulting splines.""" v_min = traits.Float(0) v_max = traits.Float(15) a_min = traits.Float(-5) a_max = traits.Float(5) j_min = traits.Float(-2.5) j_max = traits.Float(2.5) mass = traits.Float(400) q_i = traits.Float v_i = traits.Float a_i = traits.Float t_i = traits.Float q_f = traits.Float(100) v_f = traits.Float(0) a_f = traits.Float(0) t_f = traits.Float(18) plot_names = traits.List( ["Position", "Jerk", "Velocity", "Power", "Acceleration"]) active_plots = traits.List target_type = traits.Enum(('Position', 'Velocity', 'Acceleration', 'Time')) plot_container = traits.Instance(Container) recalculate = menu.Action(name="Recalculate", action="recalc") dump = menu.Action(name="Print", action="dump") save = menu.Action(name="Save", action="save") trait_view = ui.View(ui.HGroup( ui.VGroup( ui.Item(name='target_type', label='Target'), ui.VGroup(ui.Item(name='active_plots', show_label=False, editor=ui.CheckListEditor(cols=3, name='plot_names'), style='custom'), label='Show Plots', show_border=True), ui.VGroup(ui.Item(name='q_i', label='Position'), ui.Item(name='v_i', label='Velocity'), ui.Item(name='a_i', label='Acceleration'), ui.Item(name='t_i', label='Time'), label='Initial Conditions', show_border=True), ui.VGroup(ui.Item( name='q_f', label='Position', enabled_when="target_type not in ('Velocity', 'Acceleration')" ), ui.Item(name='v_f', label='Velocity', enabled_when="target_type != 'Acceleration'"), ui.Item(name='a_f', label='Acceleration'), ui.Item(name='t_f', label='Time', enabled_when="target_type == 'Time'"), label='Final Conditions:', show_border=True), ui.VGroup(ui.Item(name='v_min', label='Min Velocity'), ui.Item(name='v_max', label='Max Velocity'), ui.Item(name='a_min', label='Min Acceleration'), ui.Item(name='a_max', label='Max Acceleration'), ui.Item(name='j_min', label='Min Jerk'), ui.Item(name='j_max', label='Max Jerk'), ui.Item(name='mass', label='Vehicle Mass'), label='Constraints', show_border=True)), ui.Item('plot_container', editor=ComponentEditor(), show_label=False)), title='Cubic Spline Explorer', handler=SEButtonHandler(), buttons=[recalculate, dump, save], resizable=True, width=1000) def __init__(self): super(SplineExplorer, self).__init__() self.active_plots = self.plot_names[:] self.active_plots.remove("Power") self.calc() def calc(self): try: self.solver = TrajectorySolver(self.v_max, self.a_max, self.j_max, self.v_min, self.a_min, self.j_min) self.initial = Knot(self.q_i, self.v_i, self.a_i, self.t_i) self.final = Knot(self.q_f, self.v_f, self.a_f, self.t_f) if self.target_type == 'Position': self.spline = self.solver.target_position( self.initial, self.final) elif self.target_type == 'Velocity': self.spline = self.solver.target_velocity( self.initial, self.final) elif self.target_type == 'Acceleration': self.spline = self.solver.target_acceleration( self.initial, self.final) elif self.target_type == 'Time': self.spline = self.solver.target_time(self.initial, self.final) pos = vel = accel = jerk = power = False if "Position" in self.active_plots: pos = True if "Velocity" in self.active_plots: vel = True if "Acceleration" in self.active_plots: accel = True if "Jerk" in self.active_plots: jerk = True if "Power" in self.active_plots: power = True self.plotter = CSplinePlotter(self.spline, self.v_max, self.a_max, self.j_max, self.v_min, self.a_min, self.j_min, mass=self.mass, plot_pos=pos, plot_vel=vel, plot_accel=accel, plot_jerk=jerk, plot_power=power) self.plot_container = self.plotter.container except: self.initial = None self.final = None self.spline = None self.plot_container = Container() def display(self): self.configure_traits() def get_save_filename(self): """Get a filename from the user via a FileDialog. Returns the filename.""" dialog = FileDialog(action="save as", default_filename="spline_00", wildcard="*.png") dialog.open() if dialog.return_code == OK: return dialog.path def save(self, path): """Save an image of the plot. Does not catch any exceptions.""" # Create a graphics context of the right size win_size = self.plot_container.outer_bounds plot_gc = chaco.PlotGraphicsContext(win_size) #plot_gc.set_fill_color("transparent") # Place the plot component into it plot_gc.render_component(self.plot_container) # Save out to the user supplied filename plot_gc.save(path) def _active_plots_changed(self): self.calc() def _target_type_changed(self): self.calc()
class SectionViewer(HasTraits): section = Instance(Section) plot = Instance(Plot) plotdata = Instance(ArrayPlotData, kw={ 'x': numpy.array([]), 'y': numpy.array([]) }) #pointsx = Array(numpy.float, value=numpy.array([])) #pointsy = Array(numpy.float, value=numpy.array([])) data = Property(Array, depends_on='section.data.data_points') @cached_property def _get_data(self): try: ret = self.section.data.data_points #self.pointsx = ret[:, 0] #self.pointsy = ret[:, 1] self.plotdata.set_data('x', ret[:, 0]) self.plotdata.set_data('y', ret[:, 1]) return ret except AttributeError: return numpy.Array([[], []]) @on_trait_change('data') def replot(self): # FIXME: handle aspect ratio correctness print 'in SectionViewer.plot' self.plot.title = 'Section : %s' % self.section.type self.plot.request_redraw() def __init__(self, *l, **kw): # TODO: implement aspect ratio maintaining HasTraits.__init__(self, *l, **kw) #self.plotdata = ArrayPlotData(x=self.pointsx, y=self.pointsy) plot = Plot(self.plotdata) renderer = plot.plot(("x", "y")) #lineplot = create_line_plot((self.pointsx,self.pointsy), width=2.0) #lineplot.tools.append(PanTool(lineplot, drag_button='middle')) #lineplot.tools.append(ZoomTool(lineplot, tool_mode='box')) plot.tools.append(PanTool(plot, drag_button='left')) plot.tools.append(ZoomTool(plot, tool_mode='box')) plot.tools.append(DragZoom(plot, tool_mode='box', drag_button='right')) plot.tools.append(CustomSaveTool( plot)) #, filename='/home/pankaj/Desktop/file.png')) #plot.overlays.append(PlotLabel('Section : %s' % self.section.type,component=plot)) #plot.tools.append(PlotToolbar(plot)) plot.tools.append(TraitsTool(plot)) #plot.tools.append(ZoomTool(plot, tool_mode='box', axis='index', drag_button='right', always_on=True)) #plot.aspect_ratio = 3 #plot.request_redraw() #print plot.bounds #plot.aspect_ratio = 1 #plot.bounds = [500,300] #print plot.bounds #plot.range2d = DataRange2D(low=(0,-.5), high=(1,0.5)) #print plot.bounds for renderer in chain(*plot.plots.values()): renderer.index_mapper.stretch_data = False renderer.value_mapper.stretch_data = False renderer.index_mapper.range.low = 0 renderer.index_mapper.range.high = 1 renderer.value_mapper.range.low = -3 / 8. renderer.value_mapper.range.high = 3 / 8. self.plot = plot view = View(Item( 'plot', editor=ComponentEditor(), show_label=False, resizable=True, ), resizable=True)
class tcWindow(HasTraits): project = tcProject plot = tcPlot def __init__(self, project): self.project = project self.plot = create_timechart_container(project) self.plot_range_tools = self.plot.range_tools self.plot_range_tools.on_trait_change(self._selection_time_changed, "time") self.trait_view().title = self.get_title() def get_title(self): if self.project.filename == "dummy": return "PyTimechart: Please Open a File" return "PyTimechart:" + self.project.filename # Create an action that exits the application. status = Str("Welcome to PyTimechart") traits_view = View( HSplit( VSplit( Item('project', show_label=False, editor=InstanceEditor(view='process_view'), style='custom', width=150), # Item('plot_range_tools', show_label = False, editor=InstanceEditor(view = 'selection_view'), style='custom',width=150,height=100) ), Item('plot', show_label=False, editor=ComponentEditor()), ), toolbar=ToolBar(*_create_toolbar_actions(), image_size=(24, 24), show_tool_names=False), menubar=MenuBar(*_create_menubar_actions()), statusbar=[ StatusItem(name='status'), ], resizable=True, width=1280, height=1024, handler=tcActionHandler()) def _on_open_trace_file(self): if open_file(None) and self.project.filename == "dummy": self._ui.dispose() def _on_view_properties(self): self.plot.options.edit_traits() def _on_exit(self, n=None): self.close() sys.exit(0) def close(self, n=None): pass def _on_about(self): aboutBox().edit_traits() def _on_doc(self): browse_doc() def _selection_time_changed(self): self.status = "selection time:%s" % (self.plot_range_tools.time)
plot = Plot(self.plotdata) plot.plot(("x", "y")) plot.plot(("x", "y"), type='scatter') plot.tools.append(PanTool(plot, drag_button='left')) plot.tools.append(ZoomTool(plot, tool_mode='box')) plot.tools.append(DragZoom(plot, tool_mode='box', drag_button='right')) plot.tools.append(CustomSaveTool( plot)) #, filename='/home/pankaj/Desktop/file.png')) plot.tools.append(TraitsTool(plot)) self.plot = plot self.set_plotdata() view_variables = View(Item( 'plot', editor=ComponentEditor(), show_label=False, resizable=True, ), HGroup( Item('var_x', editor=EnumEditor(name='var_names_view')), Item('var_y', editor=EnumEditor(name='var_names_view'))), resizable=True) class OutputVariablesAdapter(TabularAdapter): def _columns_default(self): var_names = sorted(self.object.variable_names, key=lambda x: x.lower()) ret = [(var_name, self.object.variable_names.index(var_name))
class CyclesPlot(HasTraits): """ Simple plotting class with some attached controls""" plot = Instance(GridContainer) traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False), width=800, height=600, resizable=True, title="Business Cycles Plot") # Private Traits _file_path = Str _dates = Array _series1 = Array _series2 = Array _selected_s1 = Array _selected_s2 = Array def __init__(self): super(CyclesPlot, self).__init__() # Normally you'd pass in the data, but I'll hardwire things for this # one-off plot. srecs = read_time_series_from_csv("./biz_cycles2.csv", date_col=0, date_format="%Y-%m-%d") dt = srecs["Date"] # Industrial production compared with trend (plotted on value axis) iprod_vs_trend = srecs["Metric 1"] # Industrial production change in last 6 Months (plotted on index axis) iprod_delta = srecs["Metric 2"] self._dates = dt self._series1 = self._selected_s1 = iprod_delta self._series2 = self._selected_s2 = iprod_vs_trend end_x = np.array([self._selected_s1[-1]]) end_y = np.array([self._selected_s2[-1]]) plotdata = ArrayPlotData(x=self._series1, y=self._series2, dates=self._dates, selected_x=self._selected_s1, selected_y=self._selected_s2, endpoint_x=end_x, endpoint_y=end_y) cycles = Plot(plotdata, padding=20) cycles.plot(("x", "y"), type="line", color=(.2, .4, .5, .4)) cycles.plot(("selected_x", "selected_y"), type="line", marker="circle", line_width=3, color=(.2, .4, .5, .9)) cycles.plot(("endpoint_x", "endpoint_y"), type="scatter", marker_size=4, marker="circle", color=(.2, .4, .5, .2), outline_color=(.2, .4, .5, .6)) cycles.index_range = DataRange1D(low_setting=80., high_setting=120.) cycles.value_range = DataRange1D(low_setting=80., high_setting=120.) # dig down to use actual Plot object cyc_plot = cycles.components[0] # Add the labels in the quadrants cyc_plot.overlays.append( PlotLabel("\nSlowdown" + 40 * " " + "Expansion", component=cyc_plot, font="swiss 24", color=(.2, .4, .5, .6), overlay_position="inside top")) cyc_plot.overlays.append( PlotLabel("Downturn" + 40 * " " + "Recovery\n ", component=cyc_plot, font="swiss 24", color=(.2, .4, .5, .6), overlay_position="inside bottom")) timeline = Plot(plotdata, resizable='h', height=50, padding=20) timeline.plot(("dates", "x"), type="line", color=(.2, .4, .5, .8), name='x') timeline.plot(("dates", "y"), type="line", color=(.5, .4, .2, .8), name='y') # Snap on the tools zoomer = ZoomTool(timeline, drag_button="right", always_on=True, tool_mode="range", axis="index", max_zoom_out_factor=1.1) panner = PanTool(timeline, constrain=True, constrain_direction="x") # dig down to get Plot component I want x_plt = timeline.plots['x'][0] range_selection = RangeSelection(x_plt, left_button_selects=True) range_selection.on_trait_change(self.update_interval, 'selection') x_plt.tools.append(range_selection) x_plt.overlays.append(RangeSelectionOverlay(x_plt)) # Set the plot's bottom axis to use the Scales ticking system scale_sys = CalendarScaleSystem( fill_ratio=0.4, default_numlabels=5, default_numticks=10, ) tick_gen = ScalesTickGenerator(scale=scale_sys) bottom_axis = ScalesPlotAxis(timeline, orientation="bottom", tick_generator=tick_gen) # Hack to remove default axis - FIXME: how do I *replace* an axis? del (timeline.underlays[-2]) timeline.overlays.append(bottom_axis) container = GridContainer(padding=20, fill_padding=True, bgcolor="lightgray", use_backbuffer=True, shape=(2, 1), spacing=(30, 30)) # add a central "x" and "y" axis x_line = LineInspector(cyc_plot, is_listener=True, color="gray", width=2) y_line = LineInspector(cyc_plot, is_listener=True, color="gray", width=2, axis="value") cyc_plot.overlays.append(x_line) cyc_plot.overlays.append(y_line) cyc_plot.index.metadata["selections"] = 100.0 cyc_plot.value.metadata["selections"] = 100.0 container.add(cycles) container.add(timeline) container.title = "Business Cycles" self.plot = container def update_interval(self, value): # Reaching pretty deep here to get selections sels = self.plot.plot_components[1].plots['x'][0].index.metadata[ 'selections'] if not sels is None: p = self._dates >= sels[0] q = self._dates <= sels[1] msk = p & q self._selected_s1 = self._series1[msk] self._selected_s2 = self._series2[msk] # Find the index of the last point in the mask last_idx = -(msk[::-1].argmax() + 1) endpoint_x = np.array([self._series1[last_idx]]) endpoint_y = np.array([self._series2[last_idx]]) else: self._selected_s1 = self._series1 self._selected_s2 = self._series2 endpoint_x = np.array([self._series1[-1]]) endpoint_y = np.array([self._series2[-1]]) self.plot.plot_components[0].data['selected_x'] = self._selected_s1 self.plot.plot_components[0].data['selected_y'] = self._selected_s2 self.plot.plot_components[0].data['endpoint_x'] = endpoint_x self.plot.plot_components[0].data['endpoint_y'] = endpoint_y