能否用CustomJS更新Bokeh xaxis.major_label_overrides?

问题描述 投票:0回答:1

我被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)
javascript python bokeh
1个回答
0
投票

这是可能的。

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

© www.soinside.com 2019 - 2024. All rights reserved.