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
0
View Source File : main.py
License : MIT License
Project Creator : Psy-Fer
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
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):