Skip to content

Instantly share code, notes, and snippets.

@epifanio
Created June 26, 2020 20:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save epifanio/fb6123ae73dadf10e8fa2ca6a881edd0 to your computer and use it in GitHub Desktop.
Save epifanio/fb6123ae73dadf10e8fa2ca6a881edd0 to your computer and use it in GitHub Desktop.
import pandas as pd
from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models import Select
from bokeh.models.tools import HoverTool
from bokeh.plotting import figure, curdoc
df = pd.DataFrame({'2007': [10, 20, 30, 40],
'2008': [90, 60, 70, 40],
'2009': [30, 60, 70, 10],
'2010': [80, 50, 30, 10]},
index=[0, 0.5, 1, 1.5])
ds = ColumnDataSource(df)
p = figure(toolbar_location="above", x_axis_type="linear")
p.add_tools(HoverTool(tooltips=[("y", "@index")]))
line_renderer = p.line('2007', 'index', source=ds)
def handler(value, old, new):
print('value:', value, 'old:', old, 'new:', new)
print(ds.data[new])
line_renderer.glyph.x = ds.data[new]
#handler = CustomJS(args=dict(line_renderer=line_renderer), code="""
# line_renderer.glyph.x = {field: cb_obj.value};
#""")
select = Select(title="df-column:", options=list(df.columns))
#select.js_on_change('value', handler)
select.on_change('value', handler)
curdoc().add_root(column(select, p))
@epifanio
Copy link
Author

Error:

bokeh serve app6.py 
2020-06-26 22:01:04,251 Starting Bokeh server version 2.1.0 (running on Tornado 6.0.4)
2020-06-26 22:01:04,252 User authentication hooks NOT provided (default user enabled)
2020-06-26 22:01:04,254 Bokeh app running at: http://localhost:5006/app6
2020-06-26 22:01:04,254 Starting Bokeh server with process id: 45079
2020-06-26 22:01:06,810 WebSocket connection opened
2020-06-26 22:01:06,811 ServerConnection created
value: value old:  new: 2008
[90 60 70 40]
2020-06-26 22:01:08,808 error handling message
 message: Message 'PATCH-DOC' content: {'events': [{'kind': 'ModelChanged', 'model': {'id': '1040'}, 'attr': 'value', 'new': '2008'}], 'references': []} 
 error: ValueError("expected an element of either String, Dict(Enum('expr', 'field', 'value', 'transform'), Either(String, Instance(Transform), Instance(Expression), Float)) or Float, got array([90, 60, 70, 40])")
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/bokeh/server/protocol_handler.py", line 90, in handle
    work = await handler(message, connection)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/server/session.py", line 67, in _needs_document_lock_wrapper
    result = func(self, *args, **kwargs)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/server/session.py", line 261, in _handle_patch
    message.apply_to_document(self.document, self)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/protocol/messages/patch_doc.py", line 100, in apply_to_document
    doc._with_self_as_curdoc(lambda: doc.apply_json_patch(self.content, setter))
  File "/usr/local/lib/python3.8/dist-packages/bokeh/document/document.py", line 1150, in _with_self_as_curdoc
    return f()
  File "/usr/local/lib/python3.8/dist-packages/bokeh/protocol/messages/patch_doc.py", line 100, in <lambda>
    doc._with_self_as_curdoc(lambda: doc.apply_json_patch(self.content, setter))
  File "/usr/local/lib/python3.8/dist-packages/bokeh/document/document.py", line 411, in apply_json_patch
    patched_obj.set_from_json(attr, value, models=references, setter=setter)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/has_props.py", line 341, in set_from_json
    descriptor.set_from_json(self, json, models, setter)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/descriptors.py", line 610, in set_from_json
    return super().set_from_json(obj,
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/descriptors.py", line 321, in set_from_json
    self._internal_set(obj, json, setter=setter)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/descriptors.py", line 763, in _internal_set
    self._real_set(obj, old, value, hint=hint, setter=setter)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/descriptors.py", line 832, in _real_set
    self._trigger(obj, old, value, hint=hint, setter=setter)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/descriptors.py", line 909, in _trigger
    obj.trigger(self.name, old, value, hint, setter)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/model.py", line 661, in trigger
    super().trigger(attr, old, new, hint=hint, setter=setter)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/util/callback_manager.py", line 157, in trigger
    self._document._notify_change(self, attr, old, new, hint, setter, invoke)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/document/document.py", line 1042, in _notify_change
    self._trigger_on_change(event)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/document/document.py", line 1132, in _trigger_on_change
    self._with_self_as_curdoc(event.callback_invoker)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/document/document.py", line 1150, in _with_self_as_curdoc
    return f()
  File "/usr/local/lib/python3.8/dist-packages/bokeh/util/callback_manager.py", line 155, in invoke
    callback(attr, old, new)
  File "/home/epinux/dev/VisualStudioCode/NC-Plot/nc-plot-api/app6.py", line 25, in handler
    line_renderer.glyph.x = ds.data[new]
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/has_props.py", line 274, in __setattr__
    super().__setattr__(name, value)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/descriptors.py", line 539, in __set__
    self._internal_set(obj, value, setter=setter)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/descriptors.py", line 760, in _internal_set
    value = self.property.prepare_value(obj, self.name, value)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/bases.py", line 331, in prepare_value
    raise e
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/bases.py", line 324, in prepare_value
    self.validate(value)
  File "/usr/local/lib/python3.8/dist-packages/bokeh/core/property/either.py", line 109, in validate
    raise ValueError(msg)
ValueError: expected an element of either String, Dict(Enum('expr', 'field', 'value', 'transform'), Either(String, Instance(Transform), Instance(Expression), Float)) or Float, got array([90, 60, 70, 40])
^C
Interrupted, shutting down

@epifanio
Copy link
Author

epifanio commented Jun 27, 2020

Thanks to @eugene on SO I updated the code to a working version:

select and update pandas dataframe columns in bokeh plot

  • Python Callback
import pandas as pd

from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models import Select
from bokeh.models.tools import HoverTool
from bokeh.plotting import figure, curdoc

df = pd.DataFrame({'2007': [10, 20, 30, 40],
                   '2008': [90, 60, 70, 40],
                   '2009': [30, 60, 70, 10],
                   '2010': [80, 50, 30, 10]},
                  index=[0, 0.5, 1, 1.5])
                  
ds = ColumnDataSource(df)
p = figure(toolbar_location="above", x_axis_type="linear")
p.add_tools(HoverTool(tooltips=[("y", "@index")]))

line_renderer = p.line('2007', 'index', source=ds)

def handler(value, old, new):
    line_renderer.glyph.x = dict(field=new)

    
select = Select(title="df-column:", options=list(df.columns))
select.on_change('value', handler)

curdoc().add_root(column(select, p))
  • JS Callback
import pandas as pd

from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models import Select
from bokeh.models.tools import HoverTool
from bokeh.plotting import figure, curdoc

df = pd.DataFrame({'2007': [10, 20, 30, 40],
                   '2008': [90, 60, 70, 40],
                   '2009': [30, 60, 70, 10],
                   '2010': [80, 50, 30, 10]},
                  index=[0, 0.5, 1, 1.5])
ds = ColumnDataSource(df)
p = figure(toolbar_location="above", x_axis_type="linear")
p.add_tools(HoverTool(tooltips=[("y", "@index")]))

line_renderer = p.line('2007', 'index', source=ds)

handler = CustomJS(args=dict(line_renderer=line_renderer), code="""
   line_renderer.glyph.x = {field: cb_obj.value};
""")

select = Select(title="df-column:", options=list(df.columns))
select.js_on_change('value', handler)

curdoc().add_root(column(select, p))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment