class PlotWindow(HasTraits): _plot_data = Instance(ArrayPlotData) _plot = Instance(Plot) _click_tool = Instance(ClickerTool) _img_plot = Instance(ImagePlot) _right_click_avail = 0 name = Str view = View(Item(name='_plot', editor=ComponentEditor(), show_label=False), ) def __init__(self): super(HasTraits, self).__init__() # -------------- 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, 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, 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 = ClickerTool(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): """ Draws crosses on images """ 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 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): """ 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) # 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): """ 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 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()