bokeh.models.BoxEditTool

Here are the examples of the python api bokeh.models.BoxEditTool taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

2 Examples 7

0 View Source File : main.py
License : MIT License
Project Creator : Psy-Fer

def bkapp(doc):
    global signal
    global ut
    global lt
    global show_segs
    show_segs = False
    ut = 0
    lt = 0
    if signal.any():
        ut = max(signal)
        lt = min(signal)
        source = ColumnDataSource(data={
            'signal'    : signal,
            'position'  : list(range(0,len(signal)))
            })

        p = figure()

        p.line('position','signal', source=source)

        p.add_tools(HoverTool(
            tooltips=[
                ('signal', '@signal'),
                ('position', '@position'),
            ],
            formatters={
                'signal'    : 'printf',
                'position'    : 'printf'
            },
            mode='vline'
        ))

        renderer = p.multi_line([[1,1]], [[1,1]], line_width=4, alpha=0.5, color='green')
        draw_tool = FreehandDrawTool(renderers=[renderer])
        p.add_tools(draw_tool)

        src = ColumnDataSource({
            'x':[1,1,1], 'y':[1,1,1], 'width':[1,1,1], 'height':[1,1,1]
        })
        box_renderer = p.rect('x', 'y', 'width', 'height', fill_alpha=0.4, fill_color='orange', line_color='orange', source=src)
        box_draw_tool = BoxEditTool(renderers=[box_renderer], empty_value=1, num_objects = 5)
        p.add_tools(box_draw_tool)

        ut_slider = Slider(start=lt, end=max(signal), value=max(signal), name='upper_thresh', step=1, title="Upper Threshold")
        lt_slider = Slider(start=min(signal), end=ut, value=min(signal), name='lower_thresh', step=1, title="Lower Threshold")

        def ut_callback(attr, old, new):
            global signal
            global ut
            global lt
            ut = new
            new_signal = scale_outliers(signal, ut, lt)
            source.data = {
                        'signal'    : new_signal,
                        'position'  : list(range(0,len(new_signal)))
                        }
            update_segs()

        def lt_callback(attr, old, new):
            global signal
            global ut
            global lt
            lt = new
            new_signal = scale_outliers(signal, ut, lt)
            source.data = {
                        'signal'    : new_signal,
                        'position'  : list(range(0,len(new_signal)))
                        }
            update_segs()

        ut_slider.on_change('value', ut_callback)
        lt_slider.on_change('value', lt_callback)

        segments = ColumnDataSource(data={
            'top'     : [1,1],
            'bottom'  : [1,1],
            'left'    : [1,1],
            'right'   : [1,1]
            })

        button = Toggle(label="View Segments", sizing_mode="scale_width")

        def segment_handler(new):
            global show_segs
            show_segs = new
            if not new:
                segments.data = {
                    'top'     : [1,1],
                    'bottom'  : [1,1],
                    'left'    : [1,1],
                    'right'   : [1,1]
                            }
            update_segs()

        button.on_click(segment_handler)

        err_slider = Slider(start=0, end=20, value=5, name='error', step=1, title="Allowable Error")
        err_win_slider = Slider(start=0, end=100, value=50, name='err_win', step=1, title="Error Window Size")
        min_win_slider = Slider(start=0, end=500, value=150, name='min_win', step=1, title="Minimum Window Size")
        max_merge_slider = Slider(start=0, end=100, value=50, name='max_merge', step=1, title="Max Merge Distance")
        stdev_scale_slider = Slider(start=0, end=5, value=0.75, name='stdev_scale', step=0.01, title="Standard Deviation Scale Factor")
        stall_len_slider = Slider(start=0, end=5, value=0.25, name='stall_len', step=0.01, title="Stall Length")

        p.quad(top='top',bottom='bottom',left='left',right='right',source=segments,fill_alpha=0.5,fill_color='pink',line_color='pink')

        def err_callback(atrr, old, new):
            global err
            err = new
            update_segs()

        def err_win_callback(atrr, old, new):
            global err_win
            err_win = new
            update_segs()

        def min_win_callback(atrr, old, new):
            global min_win
            min_win = new
            update_segs()

        def max_merge_callback(atrr, old, new):
            global max_merge
            max_merge = new
            update_segs()

        def stdev_scale_callback(atrr, old, new):
            global stdev_scale
            stdev_scale = new
            update_segs()

        def stall_len_callback(atrr, old, new):
            global stall_len
            stall_len = new
            update_segs()

        def update_segs():
            #need to take into account the modified signal- somehow access it?
            global err
            global err_win
            global min_win
            global max_merge
            global stdev_scale
            global stall_len
            global ut
            global lt
            global show_segs
            left = None
            right = None
            if show_segs:
                sig = scale_outliers(signal, ut, lt)
                if sig.any():
                    left, right = get_segs(sig, err, err_win, min_win, max_merge, stdev_scale, stall_len)
                if left is not None and right is not None:
                    segments.data = {
                                'top'     :  np.full(len(left),1000),
                                'bottom'  :  np.full(len(left),0),
                                'left'    :  left,
                                'right'   :  right
                                }
                else:
                    segments.data = {
                        'top'     : [1,1],
                        'bottom'  : [1,1],
                        'left'    : [1,1],
                        'right'   : [1,1]
                                }


        err_slider.on_change('value', err_callback)
        err_win_slider.on_change('value', err_win_callback)
        min_win_slider.on_change('value', min_win_callback)
        max_merge_slider.on_change('value', max_merge_callback)
        stdev_scale_slider.on_change('value', stdev_scale_callback)
        stall_len_slider.on_change('value', stall_len_callback)

        doc.add_root(row(column(Spacer(height=10), ut_slider, lt_slider, Spacer(height=10), button, err_slider, err_win_slider, min_win_slider, max_merge_slider, stdev_scale_slider, stall_len_slider, Spacer(height=10), sizing_mode="stretch_height"), p, sizing_mode="stretch_both"))
        doc.theme = Theme(filename="theme.yaml")

def bk_worker():

0 View Source File : widgets.py
License : MIT License
Project Creator : smartyal

    def __init_figure(self):

        """
            initialize the time series widget, plot the lines, create controls like buttons and menues
            also hook the callbacks
        """

        self.hoverCounter = 0
        self.newHover = None
        self.hoverTool = None # forget the old hovers
        self.showBackgrounds = False
        self.showThresholds = False
        self.showMotifs = False
        self.showScores = False
        self.buttonWidth = 70

        #layoutControls = []# this will later be applied to layout() function

        settings = self.server.get_settings()
        mirror = self.server.get_mirror()

        if "width" in settings:
            self.width = settings["width"]
        if "height" in settings:
            self.height = settings["height"]

        """ 
        #set the theme
        if settings["theme"] == "dark":
            self.curdoc().theme = Theme(json=themes.darkTheme)
            self.lineColors = themes.darkLineColors
            self.plot.xaxis.major_label_text_color = themes.darkTickColor
        else:
            self.curdoc().theme = Theme(json=themes.whiteTheme)
            self.lineColors = themes.whiteLineColors
            self.plot.xaxis.major_label_text_color = themes.whiteTickColor
        """
        #self.cssClasses = {"button":"button_21","groupButton":"group_button_21","multiSelect":"multi_select_21"}
        #self.cssClasses = {"button": "button_21_sm", "groupButton": "group_button_21_sm", "multiSelect": "multi_select_21_sm"}
        #self.layoutSettings = {"controlPosition":"bottom"} #support right and bottom, the location of the buttons and tools


        #initial values
        try:
            self.rangeStart = date2secs(settings["startTime"])*1000
            self.rangeEnd = date2secs(settings["endTime"])*1000
        except:
            self.rangeStart = None
            self.rangeEnd = None
            self.logger.error("range start, end error, use default full")

        #create figure
        """
           the creation of the figure was reworked as this is a work around for a well known bug (in 1.04), see here
           https://github.com/bokeh/bokeh/issues/7497

           it's a bokeh problem with internal sync problems of frontend and backend, so what we do now is:
           1) use toolbar_location = None to avoid auto-creation of toolbar
           2) create tools by hand
           3) assign them to the figure with add_tools()
           4) create a toolbar and add it to the layout by hand
        """

        if self.server.get_mirror()["panOnlyX"][".properties"]["value"]==True:
            self.wheelZoomTool = WheelZoomTool(dimensions="width")
            self.panTool = PanTool(dimensions="width")
        else:
            self.wheelZoomTool = WheelZoomTool()#dimensions="width")
            self.panTool = PanTool()#dimensions="width")

        tools = [self.wheelZoomTool, self.panTool]
        """
        self.wheelZoomTool = WheelZoomTool()
        self.wheelZoomToolX = WheelZoomTool(dimensions = "width")
        self.panTool = PanTool()
        tools = [self.wheelZoomTool,self.wheelZoomToolX,self.panTool]
        """

        if settings["hasAnnotation"] == True:
            self.boxSelectTool = BoxSelectTool(dimensions="width")
            tools.append(self.boxSelectTool)
        elif settings["hasThreshold"] == True:
            self.boxSelectTool = BoxSelectTool(dimensions="height")
            tools.append(self.boxSelectTool)
        tools.append(ResetTool())
        self.freeZoomTool = BoxZoomTool()
        tools.append(self.freeZoomTool)








        if "yAxisType" in mirror and mirror ["yAxisType"][".properties"]["value"]=="log":
            yAxisType = "log"
        else:
            yAxisType = "linear"
        
        if "xAxisType" in mirror and mirror ["xAxisType"][".properties"]["value"]=="number":
            if yAxisType == "log":
                fig = figure(toolbar_location=None, plot_height=self.height,
                     plot_width=self.width,
                     sizing_mode="scale_width",
                     x_range=(0,1),y_axis_type=yAxisType) 
            else:
                fig = figure(toolbar_location=None, plot_height=self.height,
                     plot_width=self.width,
                     sizing_mode="scale_width",
                     x_range=(0,1),y_axis_type=yAxisType,y_range=Range1d())

        else:
            if yAxisType == "log":
                fig = figure(toolbar_location=None, plot_height=self.height,
                     plot_width=self.width,
                     sizing_mode="scale_width",
                     x_axis_type='datetime',x_range=(0,1),y_axis_type=yAxisType) 
            else:
                fig = figure(toolbar_location=None, plot_height=self.height,
                     plot_width=self.width,
                     sizing_mode="scale_width",
                     x_axis_type='datetime',x_range=(0,1),y_axis_type=yAxisType,y_range=Range1d())

        
        
        self.plot = fig

        # set the theme
        if settings["theme"] == "dark":
            self.curdoc().theme = Theme(json=themes.darkTheme)
            self.lineColors = themes.darkLineColors
            self.plot.xaxis.major_label_text_color = themes.darkTickColor
            self.plot.yaxis.major_label_text_color = themes.darkTickColor
        else:
            self.curdoc().theme = Theme(json=themes.whiteTheme)
            self.lineColors = themes.whiteLineColors
            self.plot.xaxis.major_label_text_color = themes.whiteTickColor
            self.plot.yaxis.major_label_text_color = themes.whiteTickColor


        #b1 = date2secs(datetime.datetime(2015,2,13,3,tzinfo=pytz.UTC))*1000
        #b2 = date2secs(datetime.datetime(2015,2,13,4,tzinfo=pytz.UTC))*1000
        #wid = 20*60*1000 # 20 min
        #self.boxData = ColumnDataSource({'x': [b1,b2], 'y':[0,0],'width': [5, 5],'height':[300,300],"alpha":[1,1,0.2]})

        #self.boxRect = self.plot.rect(x="x", y="y", width="width", height="height",source=self.boxData)
        #self.boxRect = self.plot.rect('x', 'y', 'width', 'height', source=self.boxData,width_units="screen")#, height_units="screen")#, height_units="screen")
        self.boxModifierTool=BoxEditTool( renderers=[],num_objects=0,empty_value=0.1)#,dimensions="width")
        self.box_modifier_init()
        #self.box_modifier_show()

        # possible attribures to boxedittool:
        # custom_icon, custom_tooltip, dimensions, empty_value, js_event_callbacks, js_property_callbacks, name, num_objects, renderers, subscribed_events
        #self.plot.add_layout(self.boxRect)
        #self.boxModifierRect.data_source.on_change("selected",self.box_cb)
        #self.boxRect.data_source.on_change("active", self.box_cb_2)

        tools.append(self.boxModifierTool)





        for tool in tools:
            fig.add_tools(tool) # must assign them to the layout to have the actual use hooked
        toolBarBox = ToolbarBox()  #we need the strange creation of the tools to avoid the toolbar to disappear after
                                   # reload of widget, then drawing an annotations (bokeh bug?)
        toolBarBox.toolbar = Toolbar(tools=tools,active_inspect=None,active_scroll=self.wheelZoomTool,active_drag = None)
        #active_inspect = [crosshair],
        # active_drag =                         # here you can assign the defaults
        # active_scroll =                       # wheel_zoom sometimes is not working if it is set here
        # active_tap
        toolBarBox.toolbar_location = "right"
        toolBarBox.toolbar.logo = None # no bokeh logo

        self.tools = toolBarBox
        self.toolBarBox = toolBarBox

        if "xAxisType" in mirror and mirror["xAxisType"][".properties"]["value"]=="number":
            if "xAxisUnit" in mirror:
               self.plot.xaxis.formatter = FuncTickFormatter(code = """
                let x=tick.toString();
                return x + " %s";
                """%mirror['xAxisUnit']['.properties']['value'])
            else:
                #no formatter
                pass
        else:
            self.plot.xaxis.formatter = FuncTickFormatter(code = """
                let local = moment(tick).tz('%s');
                let datestring =  local.format();
                return datestring.slice(0,-6);
                """%settings["timeZone"])

            self.plot.xaxis.ticker = DatetimeTicker(desired_num_ticks=5)# give more room for the date time string (default was 6)

            self.plot.xgrid.ticker = self.plot.xaxis.ticker

        self.build_second_y_axis()

        self.show_hide_scroll_label() #it must be created at startup and then visible=True/False, the later add_layout did not work

        self.refresh_plot()

        #hook in the callback of the figure
        self.plot.x_range.on_change('start', self.range_cb)
        self.plot.x_range.on_change('end', self.range_cb)
        self.plot.on_event(events.Pan, self.event_cb)
        self.plot.on_event(events.PanStart, self.event_cb)
        self.plot.on_event(events.PanEnd, self.event_cb)
        self.plot.on_event(events.LODEnd, self.event_cb)
        self.plot.on_event(events.Reset, self.event_cb)
        self.plot.on_event(events.SelectionGeometry, self.event_cb)
        self.plot.on_event(events.Tap,self.event_cb)
        #self.plot.on_event(events.MouseWheel, self.mouse_cb)


        #make the controls
        layoutControls =[]

        #Annotation drop down
        if 0: #no drop down for now
            labels=[]
            if settings["hasAnnotation"] == True:
                labels = settings["tags"]
                labels.append("-erase-")
            if settings["hasThreshold"] == True:
                labels.extend(["threshold","-erase threshold-"])
            if labels:
                menu = [(label,label) for label in labels]
                self.annotationDropDown = Dropdown(label="Annotate: "+str(labels[0]), menu=menu,width=self.buttonWidth,css_classes = ['dropdown_21'])
                self.currentAnnotationTag = labels[0]
                self.annotationDropDown.on_change('value', self.annotation_drop_down_on_change_cb)
                #self.annotation_drop_down_on_change_cb() #call it to set the box select tool right and the label
                layoutControls.append(self.annotationDropDown)

        """ 
        currently disabled
        
        # show Buttons
        # initially everything is disabled
        # check background, threshold, annotation, streaming
        self.showGroupLabels = []
        self.showGroupLabelsDisplay=[]
        if self.server.get_settings()["hasAnnotation"] == True:
            self.showGroupLabels.append("Annotation")
            self.showGroupLabelsDisplay.append("Anno")
        if self.server.get_settings()["background"]["hasBackground"]:
            self.showGroupLabels.append("Background")
            self.showGroupLabelsDisplay.append("Back")
            self.showBackgrounds = False # initially off
        if self.server.get_settings()["hasThreshold"] == True:
            self.showGroupLabels.append("Threshold")
            self.showGroupLabelsDisplay.append("Thre")
            self.showThresholds = False # initially off
        if self.server.get_settings()["hasStreaming"] == True:
            self.showGroupLabels.append("Streaming")
            self.showGroupLabelsDisplay.append("Stream")
            self.streamingMode = False # initially off
        self.showGroup = CheckboxButtonGroup(labels=self.showGroupLabelsDisplay)
        self.showGroup.on_change("active",self.show_group_on_click_cb)
        layoutControls.append(row(self.showGroup))
        """

        #make the custom buttons
        buttonControls = []
        self.customButtonsInstances = []
        if "buttons" in settings:
            self.logger.debug("create user buttons")
            #create the buttons
            for entry in settings["buttons"]:
                button = Button(label=entry["name"],width=self.buttonWidth)#,css_classes=['button_21'])
                instance = self.ButtonCb(self,entry["targets"])
                button.on_click(instance.cb)
                buttonControls.append(button)
                self.customButtonsInstances.append(instance)

        #make the debug button
        if "hasReloadButton" in self.server.get_settings():
            if self.server.get_settings()["hasReloadButton"] == True:
                #we must create a reload button
                button = Button(label="reload",width=self.buttonWidth)#, css_classes=['button_21'])
                button.on_click(self.reset_all)
                buttonControls.append(button)


        if 0: # turn this helper button on to put some debug code
            self.debugButton= Button(label="debug")
            self.debugButton.on_click(self.debug_button_cb)
            self.debugButton2 = Button(label="debug2")
            self.debugButton2.on_click(self.debug_button_2_cb)
            buttonControls.append(self.debugButton)
            buttonControls.append(self.debugButton2)


        layoutControls.extend(buttonControls)

        #build the layout


        self.layout = layout([row(children=[self.plot, self.tools], sizing_mode="fixed")], row(layoutControls, width=int(self.width*0.6),sizing_mode="scale_width"))
        #self.layout = layout([row(children=[self.plot, self.tools], sizing_mode="fixed")])

        if self.server.get_settings()["hasAnnotation"] == True:
            self.init_annotations() # we create all annotations that we have into self.annotations

        if "hasEvents" in self.server.get_settings() and self.server.get_settings()["hasEvents"] == True:
            self.init_events()


    def init_additional_elements(self):