我被Bokeh CustomJS卡住了整整一周,如果有人能帮我解决这个问题,我将非常高兴。
我正在使用CustomJS使用Bokeh库创建交互式的独立蜡烛图,想知道我是否可以更新Bokeh xaxis.major_label_overrides。xaxis.major_label_overrides
的回调。
烛台在x轴上用索引号绘制,确保周末的空隙被移除。而对于 Select
小组件,我通过使用CustomJS回调来改变源CDB(CBD是根据其颗粒度单独创建的),从而可以改变蜡烛图的颗粒度。
然后,接下来我想让图表变成什么样子,就是根据选择的粒度来改变x轴的日期。由于x轴上的日期是用索引号代替的,所以由 xaxis.major_label_overrides
我试着在回调(granularity change)被触发时更新它们。
以下是没有成功的代码。(没有 xaxis.major_label_overrides
回调,确实有效)。) 由于我对JS几乎没有经验,我相信有些JS代码对预期的功能是致命的。
#--Omitted: Some codes to create DataFrames with different granularities--#
#CDS for plotting
source = ColumnDataSource(data=df_M5) #default source
source_M1 = ColumnDataSource(data=df_M1)
source_M5 = ColumnDataSource(data=df_M5)
#creating dictionary list for index substitutions
overridetime_M1 = {i: date.strftime('%Y/%m/%d %H:%M') for i, date in enumerate(df_M1['time'])}
overridetime_M5 = {i: date.strftime('%Y/%m/%d %H:%M') for i, date in enumerate(df_M5['time'])}
plt1 = figure()
#--Omitted: Some codes to draw candlesticks using source--#
#default x-axis overriding
plt1.xaxis.major_label_overrides = overridetime_M5
select = Select(title="Option:", value="M5", options=["M1", "M5"])
callback_granularity = CustomJS(args=dict(
source=source,
source_M1=source_M1,
source_M5=source_M5,
overridetime=overridetime,
overridetime_M1=overridetime_M1,
overridetime_M5=overridetime_M5,
select=select
plt1=plt1
), code="""
var sdata = source.data;
var f = select.value;
var data_M1 = source_M1.data;
var data_M5 = source_M5.data;
var ot = overridetime;
var ot_M1 = overridetime_M1;
var ot_M5 = overridetime_M5;
if (f == "M1") {
for (var k in sdata) {
sdata[k] = [];
sdata[k] = data_M1[k];
}
plt1.xaxis.major_label_overrides = overridetime_M1;
} else if (f == "M5") {
for (var k in sdata) {
sdata[k] = [];
sdata[k] = data_M5[k];
}
plt1.xaxis.major_label_overrides = overridetime_M5;
};
source.change.emit();
plt1.change.emit();
""")
select.js_on_change('value', callback_granularity)
这是可能的。
from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import Select, CustomJS
from bokeh.plotting import figure
p = figure()
p.circle(0, 0)
s = Select(options=[('no', 'Do not override'),
('yes', 'Override')],
value='no')
s.js_on_change('value',
CustomJS(args=dict(x_axis=p.xaxis[0]),
code="x_axis.major_label_overrides = cb_obj.value === 'no' ? {} : {0: 'Hello'};"))
show(column(p, s))
你的代码的问题是你使用了 xaxis
. 在Bokeh中,它是一个 "splattable list "的axes(意思是,任何属性改变或方法调用都会将操作应用到列表中的每一个项目),但在BokehJS中,它是一个普通的axes列表。但在BokehJS中,它是一个常规的轴列表。