通过选择图表刷新散景数据表

时间:2018-01-12 03:39:24

标签: python datatable callback widget bokeh

我正在尝试通过选择一个绘图更新Bokeh DataTable。不确定为什么它没有得到更新?在下面的代码中,source_devon是绘图的ColumnDataSource-我希望Datatable在我们选择特定时更新part.Currently DataTable已创建(初始化),但它在选择时没有变化

from bokeh.io import curdoc
from bokeh.layouts import layout,row
from bokeh.models import CDSView,HoverTool,GroupFilter,ColumnDataSource,Button,Select,TextInput,Slider,DataTable,TableColumn,DateFormatter,LinearAxis,Range1d,CustomJS,Rect
from bokeh.plotting import figure,output_file,show
from datetime import datetime, timedelta
from bokeh.client import push_session
import pandas as pd
import numpy as np



TOOLS='pan,wheel_zoom,box_zoom,reset,tap,save,lasso_select,xbox_select'

# Select widget
ccy_options = ['AUDUSD', 'USDJPY']
menu = Select(options=['AUDUSD','USDJPY'], value='AUDUSD')
slider = Slider(start=-1000, end=10000, step=1000, value=-1000, title='Volume Cutoff')


# Function to get Order/Trade/Price Datasets
def get_combined_dataset(src,name):
df = src[(src.CCYPAIR == name)].copy()
return ColumnDataSource(data=df)

# Function to Make Plots
def make_plot(source_order):
x  = 'DATE'
y  = 'PRICE'
y1 = 'Volume'
size = 10
alpha = 0.5
hover = HoverTool(
tooltips = [
    ('OrderId', '@ORDER_ID_108'),
    ('Volume', '@Volume'),
    ('Price', '@PRICE')
    ]
)
view1 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='ORDER'),GroupFilter(column_name='SIDE',group='B')])
view2 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='ORDER'),GroupFilter(column_name='SIDE',group='S')])
view3 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='TRADE'),GroupFilter(column_name='SIDE',group='B')])
view4 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='TRADE'),GroupFilter(column_name='SIDE',group='S')])
view5 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='DevonTrade')])
view6 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='Prices')])
plot2 = figure(plot_width=1000, plot_height=300, tools=[hover, TOOLS], 
   title='Agg. Position Snapshot for Devon',
   x_axis_label='Date', y_axis_label='Price',x_axis_type="datetime")

plot = figure(plot_width=1000,    plot_height=300,tools=TOOLS,x_axis_type="datetime",title='Order/Execution Snapshot with Price Levels')
plot.circle(x=x,y=y,source=source_order,view=view1,alpha=0.6,color='blue')
plot.circle(x=x,y=y,source=source_order,view=view2,alpha=0.6,color='red')
plot.triangle(x=x,y=y,source=source_order,view=view3,alpha=0.6,color='blue')
plot.triangle(x=x,y=y,source=source_order,view=view4,alpha=0.6,color='red')
plot.line(x=x,y=y,source=source_order,view=view6,color='green')
plot2.line(x=x,y=y1,source=source_order,view=view5,color='blue')
plot.legend.location = 'top_left'
return plot,plot2

def make_table(source):
columns = [
TableColumn(field='DATE', title="DATE", formatter=DateFormatter()),
TableColumn(field='CCYPAIR', title="CCYPAIR"),
    TableColumn(field='SIDE', title="SIDE"),
    TableColumn(field='PRICE', title="PRICE"),
    TableColumn(field='TYPE', title="TYPE"),
    TableColumn(field='Volume', title="Volume"),
    TableColumn(field='ORDER_ID_108', title="ORDERID"),
]
data_table = DataTable(source=source, columns=columns, width=1000, height=200)
return data_table
def update_plot(attrname, old, new):
newccy = menu.value
newvalue = slider.value
src_data_table = get_combined_dataset(Combined,newccy)
DisplayData.data.update(src_data_table.data)


def update_plot(attrname, old, new):
newccy = menu.value
newvalue = slider.value
src_data_table = get_combined_dataset(Combined,newccy)
DisplayData.data.update(src_data_table.data)


def selection_change(attrname, old, new):
data =  get_all_dataset(Combined,menu.value)
selected = DisplayData.selected['1d']['indices']
if selected:
   data  = data.iloc[selected, :]
   update_datatable(data)

def update_datatable(data):
src_data_table = get_combined_dataset(data,menu.value)
s2.data.update(src_data_table.data)

# Input Files    
date_today = datetime.now()
days = pd.date_range(date_today, date_today + timedelta(5), freq='D')
Combined1 = {'DATE': days,
 'CCYPAIR': ['USDJPY', 'USDJPY', 'USDJPY','USDJPY', 'USDJPY', 'USDJPY'],
 'SIDE' : ['B', 'B', 'B','B', 'B', 'B'],
 'PRICE': [100.00, 200.00, 300.00,100.00, 200.00, 300.00],
 'TYPE' : ['ORDER', 'ORDER', 'ORDER','DevonTrade', 'DevonTrade', 'DevonTrade'],
 'Volume': [100, 200, 300, 100, 200, 300],
 'ORDER_ID_108':  [111,222,333,111,222,333]
   }
Combined = pd.DataFrame(Combined1)


DisplayData =  get_combined_dataset(Combined,menu.value)
plot,plot2 =  make_plot(DisplayData)
menu.on_change('value', update_plot)
plot.x_range = plot2.x_range

s2 = ColumnDataSource(data=dict(DATE=[],CCYPAIR=[],SIDE=[],PRICE=[],TYPE=[],Volume=[],ORDER_ID_108=[]))

columns = [
    TableColumn(field='DATE', title="DATE", formatter=DateFormatter()),
    TableColumn(field='CCYPAIR', title="CCYPAIR"),
    TableColumn(field='SIDE', title="SIDE"),
    TableColumn(field='PRICE', title="PRICE"),
    TableColumn(field='TYPE', title="TYPE"),
    TableColumn(field='Volume', title="Volume"),
    TableColumn(field='ORDER_ID_108', title="ORDER_ID_108")
]
data_table = DataTable(source=s2,columns=columns,width=1000, height=200)



layout = layout([menu],
            [plot],
            [plot2],
            [data_table])
curdoc().add_root(layout)

DisplayData.on_change('selected', selection_change)

2 个答案:

答案 0 :(得分:1)

您的主要问题是您要更新的源与包含原始数据的源没有相同的字段。在你的回调中,你试图访问d2 [' DATES']和d2 [' PRICES'],但是你将这些字段定义为' x'和'。请参阅下面已更正此问题的代码。我还定义了第二个绘图的绘图范围,以便显示数据。

from bokeh.io import curdoc
from bokeh.layouts import layout,row
from bokeh.models import HoverTool,ColumnDataSource,Button,Select,TextInput,Slider,DataTable,TableColumn,DateFormatter,LinearAxis,Range1d,CustomJS,Rect
from bokeh.plotting import figure,output_file,show
from datetime import datetime, timedelta
from bokeh.client import push_session
import pandas as pd
import numpy as np


TOOLS='pan,wheel_zoom,box_zoom,reset,tap,save,lasso_select,xbox_select'

# Select widget
menu = Select(options=['AUDUSD','USDJPY'], value='USDJPY')

# Function to get Order/Trade/Price Datasets
def get_order_dataset(src,name):
    df = src[(src.CCYPAIR == name) & (src.TYPE == 'ORDER') & (src.SIDE == 'B')].copy()
    return ColumnDataSource(data=df)

# Function to Make Plots
def make_plot(source_order):
    x  = 'DATE'
    y  = 'PRICE'
    size = 10
    alpha = 0.5
    hover = HoverTool(
    tooltips = [
        ('OrderId', '@ORDER_ID_108'),
        ('Volume', '@Volume'),
        ('Price', '@PRICE')
        ]
    )

    plot = figure(plot_width=1000, plot_height=300, tools=[hover, TOOLS], 
       title='Order/Execution Snapshot with Price Levels',
       x_axis_label='Date', y_axis_label='Price',x_axis_type="datetime",active_drag="xbox_select")

    plot.circle(x=x, y=y, size=size, alpha=alpha, color='blue',
            legend='Orders', source=source_order,selection_color="orange")
    plot.legend.location = 'top_left'
    return plot

def update_plot(attrname, old, new):
    newccy = menu.value
    src_order = get_order_dataset(Combined,newccy)
    source_order.data.update(src_order.data)


date_today = datetime.now()
days = pd.date_range(date_today, date_today + timedelta(2), freq='D')
Combined1 = {'DATE': days,
     'CCYPAIR': ['USDJPY', 'USDJPY', 'USDJPY'],
     'SIDE' : ['B', 'B', 'B'],
     'PRICE': [100.00, 200.00, 300.00],
     'TYPE' : ['ORDER', 'ORDER', 'ORDER'],
     'Volume': [100, 200, 300],
     'ORDER_ID_108':  [111,222,333]
       }
Combined = pd.DataFrame(Combined1)

source_order = get_order_dataset(Combined,menu.value)

plot =  make_plot(source_order)
menu.on_change('value', update_plot)

s2 = ColumnDataSource(data=dict(DATE=[], PRICE=[]))
p2 = figure(plot_width=1000, plot_height=400,
    tools="", title="Watch Here",x_axis_type="datetime", y_range=(90,310),x_range=(days[0],days[-1]))
p2.circle('DATE', 'PRICE', source=s2, alpha=0.6, size=10)

source_order.callback = CustomJS(args=dict(s2=s2), code="""
var inds = cb_obj.selected['1d'].indices;
console.log(inds)
var d1 = cb_obj.data;
var d2 = s2.data;
d2['DATE'] = []
d2['PRICE'] = []
for (i = 0; i < inds.length; i++) {
    d2['DATE'].push(d1['DATE'][inds[i]])
    d2['PRICE'].push(d1['PRICE'][inds[i]])
}
s2.change.emit();""")

layout = layout([menu],
        [plot],
        [p2])
curdoc().add_root(layout)

答案 1 :(得分:0)

from bokeh.io import curdoc
from bokeh.layouts import layout,row
from bokeh.models import  CDSView,HoverTool,GroupFilter,ColumnDataSource,Button,Select,TextInput,Slider,DataTable,TableColumn,DateFormatter,LinearAxis,Range1d,CustomJS,Rect
from bokeh.plotting import figure,output_file,show
from datetime import datetime, timedelta
from bokeh.client import push_session
import pandas as pd
import numpy as np



TOOLS='pan,wheel_zoom,box_zoom,reset,tap,save,lasso_select,xbox_select'

# Select widget
ccy_options = ['AUDUSD', 'USDJPY']
menu = Select(options=['AUDUSD','USDJPY'], value='AUDUSD')
slider = Slider(start=-1000, end=10000, step=1000, value=-1000,     title='Volume Cutoff')


# Function to get Order/Trade/Price Datasets
def get_combined_dataset(src,name):
df = src[(src.CCYPAIR == name)].copy()
return ColumnDataSource(data=df)

# Function to Make Plots
def make_plot(source_order):
x  = 'DATE'
y  = 'PRICE'
y1 = 'Volume'
size = 10
alpha = 0.5
hover = HoverTool(
tooltips = [
('OrderId', '@ORDER_ID_108'),
('Volume', '@Volume'),
('Price', '@PRICE')
]
)
view1 = CDSView(source=source_order, filters=   [GroupFilter(column_name='TYPE',group='ORDER'),GroupFilter(column_name='SIDE',group='B')])
view2 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='ORDER'),GroupFilter(column_name='SIDE',group='S')])
view3 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='TRADE'),GroupFilter(column_name='SIDE',group='B')])
view4 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='TRADE'),GroupFilter(column_name='SIDE',group='S')])
view5 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='DevonTrade')])
view6 = CDSView(source=source_order, filters=[GroupFilter(column_name='TYPE',group='Prices')])
plot2 = figure(plot_width=1000, plot_height=300, tools=[hover, TOOLS], 

标题=&#39;此Agg。 Devon&#39;的位置快照,    x_axis_label =&#39;日期&#39;,y_axis_label =&#39;价格&#39;,x_axis_type =&#34;日期时间&#34;)

plot = figure(plot_width=1000,    plot_height=300,tools=TOOLS,x_axis_type="datetime",title='Order/Execution Snapshot with Price Levels')
plot.circle(x=x,y=y,source=source_order,view=view1,alpha=0.6,color='blue')
plot.circle(x=x,y=y,source=source_order,view=view2,alpha=0.6,color='red')
plot.triangle(x=x,y=y,source=source_order,view=view3,alpha=0.6,color='blue')
plot.triangle(x=x,y=y,source=source_order,view=view4,alpha=0.6,color='red')
plot.line(x=x,y=y,source=source_order,view=view6,color='green')
plot2.line(x=x,y=y1,source=source_order,view=view5,color='blue')
plot.legend.location = 'top_left'
return plot,plot2

def make_table(source):
columns = [
TableColumn(field='DATE', title="DATE", formatter=DateFormatter()),
TableColumn(field='CCYPAIR', title="CCYPAIR"),
TableColumn(field='SIDE', title="SIDE"),
TableColumn(field='PRICE', title="PRICE"),
TableColumn(field='TYPE', title="TYPE"),
TableColumn(field='Volume', title="Volume"),
TableColumn(field='ORDER_ID_108', title="ORDERID"),
]
data_table = DataTable(source=source, columns=columns, width=1000, height=200)
return data_table
def update_plot(attrname, old, new):
newccy = menu.value
newvalue = slider.value
src_data_table = get_combined_dataset(Combined,newccy)
DisplayData.data.update(src_data_table.data)


def update_plot(attrname, old, new):
newccy = menu.value
newvalue = slider.value
src_data_table = get_combined_dataset(Combined,newccy)
DisplayData.data.update(src_data_table.data)


def selection_change(attrname, old, new):
data =  get_all_dataset(Combined,menu.value)
selected = DisplayData.selected['1d']['indices']
if selected:
 data  = data.iloc[selected, :]
update_datatable(data)

def update_datatable(data):
src_data_table = get_combined_dataset(data,menu.value)
s2.data.update(src_data_table.data)

# Input Files    
date_today = datetime.now()
days = pd.date_range(date_today, date_today + timedelta(5), freq='D')
Combined1 = {'DATE': days,
'CCYPAIR': ['USDJPY', 'USDJPY', 'USDJPY','USDJPY', 'USDJPY', 'USDJPY'],
'SIDE' : ['B', 'B', 'B','B', 'B', 'B'],
'PRICE': [100.00, 200.00, 300.00,100.00, 200.00, 300.00],
'TYPE' : ['ORDER', 'ORDER', 'ORDER','DevonTrade', 'DevonTrade', 'DevonTrade'],
 'Volume': [100, 200, 300, 100, 200, 300],
 'ORDER_ID_108':  [111,222,333,111,222,333]
  }
 Combined = pd.DataFrame(Combined1)


 DisplayData =  get_combined_dataset(Combined,menu.value)
 plot,plot2 =  make_plot(DisplayData)
 menu.on_change('value', update_plot)
 plot.x_range = plot2.x_range

 s2 = ColumnDataSource(data=dict(DATE=[],CCYPAIR=[],SIDE=[],PRICE=[],TYPE= [],Volume=[],ORDER_ID_108=[]))

 columns = [
 TableColumn(field='DATE', title="DATE", formatter=DateFormatter()),
 TableColumn(field='CCYPAIR', title="CCYPAIR"),
 TableColumn(field='SIDE', title="SIDE"),
 TableColumn(field='PRICE', title="PRICE"),
 TableColumn(field='TYPE', title="TYPE"),
 TableColumn(field='Volume', title="Volume"),
 TableColumn(field='ORDER_ID_108', title="ORDER_ID_108")
 ]
 data_table = DataTable(source=s2,columns=columns,width=1000, height=200)



 layout = layout([menu],
                 [plot],
                 [plot2],
                 [data_table])
 curdoc().add_root(layout)

 DisplayData.on_change('selected', selection_change)