Skip to content

Instantly share code, notes, and snippets.

@jni
Created September 25, 2018 07:17
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 jni/f88142a1783f5e16fbd3a67630f0ab95 to your computer and use it in GitHub Desktop.
Save jni/f88142a1783f5e16fbd3a67630f0ab95 to your computer and use it in GitHub Desktop.
attempt to save csv of selection from bokeh plot (not working)
"""Run this example as: python save_selection.py
Then navigate to localhost:5000
Use python save_selection.py -h for more options.
"""
import base64
import pandas as pd
import numpy as np
from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler
from bokeh.plotting import figure
from bokeh.layouts import layout
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import Button
def scatterplot(source):
tools = ['pan', 'box_select', 'wheel_zoom', 'reset']
scatter = figure(title='scatterplot', tools=tools,
active_drag='box_select')
scatter.circle(source=source, x='x', y='y')
return scatter
def save_selected(dataframe, selection):
data = dataframe.iloc[selection]
print(f'I got your df right here! {data.shape}')
csv = data.to_csv()
b64 = base64.b64encode(csv.encode()).decode() # str -> bytes -> b64 -> str
jscode = f"""
var link = document.createElement("a");
link.href = "data:text/csv;base64,{b64}";
link.download = "selected_data.csv";
link.target = "_blank";
link.style.visibility = "hidden";
console.log("saving selected data:");
console.log("{b64}");
link.dispatchEvent(new MouseEvent("click"));
"""
print('b64 encoded: ', b64)
return CustomJS(code=jscode)
def generate_makedoc_function(dataframe):
def makedoc(doc):
source = ColumnDataSource(dataframe)
scatter = scatterplot(source)
savebutton = Button(label='download selected points')
savebutton.js_on_click(save_selected(dataframe, selection=[]))
def update_selection(attr, old, new):
# js_on_click appends a callback, but we want to replace it.
# so, we clear first.
savebutton.js_property_callbacks.clear()
new_js_callback = save_selected(dataframe, selection=new.indices)
savebutton.js_on_click(new_js_callback)
source.on_change('selected', update_selection)
page_content = layout([[scatter], [savebutton]])
doc.title = 'save selected points!'
doc.add_root(page_content)
return makedoc
def main(path='/', port=5000):
df = pd.DataFrame({'x': np.random.random(100),
'y': np.random.random(100),
'useful': np.random.randint(0, 100, size=100)})
apps = {path: Application(FunctionHandler(generate_makedoc_function(df)))}
server = Server(apps, port=port, allow_websocket_origin=['*'])
server.run_until_shutdown()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment