问题
I am trying to use a slider to update my Bokeh Plot. I am finding it difficult to achieve it using pandas dataframe(did not find any examples so far). The other way is to use the "columndatasource" (found some examples over forums) but still not able to achieve the functionality. So I have two columns, X axis is date and the Y axis is Volume. I want to change my Y values based on slider input. I am able to see the plot but the slider functionality is not working
Any help will be very much appreciable.
source = ColumnDataSource(data=dict(x=df2['Date'],y=df2['Vol']))
S1 = figure(plot_width=400,plot_height=400,tools=TOOLS1,title="Volume Per Day",x_axis_type="datetime")
S1.line('x','y',source=source)
callback_test = CustomJS(args=dict(source=source), code="""
var data = source.get('data');
var s_val = cb_obj.value
x = data['x']
y = data['y']
console.log(cb_obj)
for (i = 0; i < s_val; i++) {
y[i] = y[i]
}
source.trigger('change');
""")
slider = Slider(start=0, end= max_Vol, value=1, step=100,title="Vol Per Day",callback=callback_test)
回答1:
You are trying to update the range of data that is plotted using a slider.
When you do:
y = data['y']
for (i = 0; i < s_val; i++) {
y[i] = y[i]
}
the python equivalent would be, if y is some array with length>s_val:
for i in range(s_val):
y[i] = y[i]
This just replaces the elements from 0 to s_val-1 by themselves and doesn't change the rest of the list.
You can do two things:
- update the displayed axis range directly
- use an empty source that you will fill from your existing source based on the slider value
.
source = ColumnDataSource(data=dict(x=df2['Date'],y=df2['Vol']))
fill_source = ColumnDataSource(data=dict(x=[],y=[]))
S1 = figure(plot_width=400,plot_height=400,tools=TOOLS1,title="Volume Per Day",x_axis_type="datetime")
S1.line('x','y',source=fill_source)
callback_test = CustomJS(args=dict(source=source,fill_source=fill_source), code="""
var data = source.data;
var fill_data = fill_source.data;
var s_val = cb_obj.value;
fill_data['x']=[];
fill_data['y']=[];
for (i = 0; i < s_val; i++) {
fill_data['y'][i].push(data['y'][i]);
fill_data['x'][i].push(data['x'][i]);
}
fill_source.trigger('change');
""")
回答2:
Here a working example hope u can make it :)
from os.path import dirname, join
import pandas as pd
from bokeh.layouts import row, widgetbox
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import DateRangeSlider,DatePicker,DateFormatter, DataTable, TableColumn, NumberFormatter
from bokeh.io import curdoc
from datetime import datetime,date
import datetime
df = pd.read_csv(join(dirname(__file__), 'test.csv'))
df['dat'] = pd.to_datetime(df['date'])
source = ColumnDataSource(data=dict())
def update():
current = df[(df['dat'] >= pd.to_datetime(slider.value[0])) & (df['dat'] <= pd.to_datetime(slider.value[1]))]
source.data = {
'opens' : current.open,
'dates' : current.date,
}
slider = DateRangeSlider(title="Date Range: ", start=date(2010, 1, 1), end=date.today(), value=(date(2017, 9, 7),date.today()), step=1)
slider.on_change('value', lambda attr, old, new: update())
columns = [
TableColumn(field="dates", title="Date" ,formatter=DateFormatter()),
TableColumn(field="opens", title="open"),
data_table = DataTable(source=source, columns=columns, width=800)
controls = widgetbox(slider)
table = widgetbox(data_table)
curdoc().add_root(row(controls, table))
update()
here is data in the the test.csv file
date,open
951868800000,102
951955200000,100.5
952041600000,107.25
952300800000,109.94
952387200000,106
952473600000,103
952560000000,106.5
952646400000,107.62
952905600000,104
952992000000,107.75
953078400000,107.5
953164800000,109
953251200000,108.25
953510400000,110
953596800000,112.81
953683200000,114.5
953769600000,115.87
953856000000,115.37
954115200000,125
954201600000,125.75
954288000000,122.31
954374400000,118.87
954460800000,122.62
954720000000,120
954806400000,121.5
954892800000,120.5
954979200000,123.5
955065600000,123.5
955324800000,124.75
955411200000,121.62
955497600000,119.62
955584000000,112.5
955670400000,109.81
955929600000,103.87
956016000000,112.25
run code using bokeh serve filename.py
来源:https://stackoverflow.com/questions/43579881/bokeh-plot-update-using-slider