Reputation: 2673
I want to create a custom bokeh widget without using JavaScript, i.e. without following the bokeh documentation on Adding A Custom Widget. The example below demonstrates the creation of a custom widget in PyQt4 (I use this a lot), and what I would expect to work in bokeh along with the error message I get.
Is there some other way to create a custom widget in bokeh without using JavaScript? Specifically I am trying to create a custom slider with small - and + buttons on each side that increment / decrement the slider by 1 step. I want to use this custom widget in many applications so I want it defined as its own class with on_change method linked to the slider on_change method. There are other custom widgets in bokeh I want to make (without JS!) and I would like to know if this is even possible.
# this works as a base to develop custom PyQt4 widgets
from PyQt4 import QtGui
import sys
class NewWidget(QtGui.QWidget):
def __init__(self):
super().__init__()
app = QtGui.QApplication([])
widget = NewWidget()
widget.show()
sys.exit(app.exec_())
# this does not work as a base to develop custom bokeh widgets
# when run, a tab opens with the message
# Bokeh Error
# Model `NewWidget' does not exist. This could be due to a widget
# or a custom model not being registered before first usage.
from bokeh.plotting import show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import Widget
class NewWidget(Widget):
def __init__(self):
super().__init__()
new = NewWidget()
show(widgetbox(new))
UPDATE: The specific custom widget I am attempting to create is a Slider with a Button on each side (on the left labeled '-', on the right labeled '+') that change the Slider value by 1 step. This is used to fine-tune the value of a Slider so the mouse is not required to exactly hit a target value. I created this custom widget by linking default Slider and Button objects and it renders in the browser, but the callback functionality is not working (specifically the Slider 'on_change' method).
Is this custom widget straightforward to implement with bokeh and JS? Is there an online reference that may provide hints without diving too deep into JS.
Upvotes: 2
Views: 2172
Reputation: 34568
Bokeh is a library for generating plot and visualization apps in modern browsers (or embedded HTML widgets). It's composed of two essential parts. The python side of Bokeh is really just a sophisticated "wrapper" or "binding" that ultimately produces a declarative JSON document, which in turns drives a JavaScript library (BokehJS) that actually does all the work in the browser.
Extending Bokeh necessarily means providing both sides of that equation: You have to provide a (typically very minimal) python declaration of the extension, that really just specifies the information needed to automatically generating the JSON format I described above. And you also have to provide a JavaScript (or TypeScript) implementation for the extension, that actually does all the work in the browser.
Since browsers have no ability to run Python code, the implementation necessarily has to be JavaScript.
There are some libraries such as Flexx and Brython that can "transpile" python into JavaScript. You might find them useful as a means to avoid writing JavaScript directly, but these libraries often have quirks and specific deficiencies in certain use cases, so YMMV.
Here is a complete example that uses a CustomJS
callback on a button to update a slider:
from bokeh.models import Button, CustomJS, Slider
from bokeh.layouts import row
from bokeh.io import output_file, show
slider = Slider(start=0, end=10, value=0, step=0.1)
button = Button()
button.callback = CustomJS(args=dict(slider=slider), code="""
slider.value += 0.1
""")
output_file("foo.html")
show(row(slider, button))
Upvotes: 5