是否可以使用 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 中,它是一个常规的轴列表。