是否可以使用 CustomJS 更新 Bokeh xaxis.major_label_overrides?
Is it possible to update Bokeh xaxis.major_label_overrides with CustomJS?
我整个星期都在使用 Bokeh CustomJS,如果有人能帮助我解决这个问题,我会很高兴。
我正在使用 CustomJS 使用 Bokeh 库创建交互式独立烛台图表,想知道我是否可以在每次回调时更新 xaxis.major_label_overrides
。
烛台在 x 轴上标有索引号,确保周末缺口被移除。使用 Select
小部件,我可以通过使用 CustomJS 回调更改源 CDB 来更改烛台的粒度(CBD 是根据其粒度单独创建的)。
然后,我希望图表接下来的样子是根据所选的粒度更改 x 轴日期。由于 x 轴上的日期被 xaxis.major_label_overrides
替换为索引号,我尝试在触发回调(粒度更改)时更新它们。
以下是无法运行的代码。 (没有 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" 轴(意思是,任何属性更改或方法调用都会将操作应用于列表中的每个项目)。但在 BokehJS 中,它是一个常规的轴列表。
我整个星期都在使用 Bokeh CustomJS,如果有人能帮助我解决这个问题,我会很高兴。
我正在使用 CustomJS 使用 Bokeh 库创建交互式独立烛台图表,想知道我是否可以在每次回调时更新 xaxis.major_label_overrides
。
烛台在 x 轴上标有索引号,确保周末缺口被移除。使用 Select
小部件,我可以通过使用 CustomJS 回调更改源 CDB 来更改烛台的粒度(CBD 是根据其粒度单独创建的)。
然后,我希望图表接下来的样子是根据所选的粒度更改 x 轴日期。由于 x 轴上的日期被 xaxis.major_label_overrides
替换为索引号,我尝试在触发回调(粒度更改)时更新它们。
以下是无法运行的代码。 (没有 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" 轴(意思是,任何属性更改或方法调用都会将操作应用于列表中的每个项目)。但在 BokehJS 中,它是一个常规的轴列表。