【问题标题】:CustomJs callbacks not updating data source for plotCustomJs 回调未更新绘图的数据源
【发布时间】:2019-09-06 23:58:35
【问题描述】:

我正在尝试根据图 1 的悬停高值更新图 2 的数据源,以便根据图 1 中的数据在图 2 中创建一个随附的可视化项。

问题是我可以从回调内部的 rect 中获取数据并将其格式化为线图的 x 和 y,但它不会更新绘图,只会从中删除占位符值。 数据对象包含需要在p2(折线图)中显示的x和y值,并且长度和格式相同,不知道为什么它不改变sourceLine ColumnDataSource

#hover tool for additional plots
p2 = figure(plot_width = 900, plot_height = 350)

#initial data source
sourceLine = ColumnDataSource(data = {'x': [2, 3, 5, 6, 8, 7], 'y': [6, 4, 3, 8, 7, 5]})

#line to be updated
ln = p2.line(x = 'x', y = 'y', line_width = 2, source = sourceLine.data)

#callback
callback = CustomJS(args={'rect': rc.data_source.data, 'line': ln.data_source}, code="""

var rdataYear = rect.YEAR;
var rdataAgeGroup = rect.AGE_GROUP;
var rdataDeaths = rect.DEATHS;

var data = {'x': [], 'y': []};
var deaths = [];
var years = [1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017
]

var indices = cb_data.index['1d'].indices;


var newarr = rect.AGE_GROUP.map((e,i) => e === rdataAgeGroup[indices] ? i : undefined).filter(x => x);

for (var i = 0; i < newarr.length; i++){
        var index = newarr[i];
        deaths.push(rdataDeaths[index])
}

//data that needs to be inside p2 line
data['x'].push(years)
data['y'].push(deaths)

line.data = data;
line.change.emit();
""")

#hover tool with the callback 
p1.add_tools(HoverTool(tooltips=[('Year', '@YEAR'), ('Age Group', '@AGE_GROUP'),('Deaths', '@DEATHS'),('Rate', '@RATE')], callback=callback))


我想让回调(数据)的输出更新 p2.line 的 x 和 y,我对 python 有点陌生,散景有点时髦,所以我真的很感激一些帮助 :)

【问题讨论】:

    标签: javascript python bokeh


    【解决方案1】:

    此行不正确:

    ln = p2.line(x = 'x', y = 'y', line_width = 2, source = sourceLine.data)
    

    source 的值应该是ColumnDataSource 本身:

    ln = p2.line(x = 'x', y = 'y', line_width = 2, source = sourceLine)
    

    当您传递.data 之类的字典时,Bokeh 会自动为您创建一个内部 CDS,为方便起见,但现在字形使用的这个新 CDS 与您在回调中更新的 CDS 无关。

    另外,不要将['1d'] 语法用于选择索引。它现在已经被弃用了很长时间,并且保证在今年年底之前完全被移除。而是:

    var indices = cb_data.index.indices
    

    此外,您的 JS 实际上并没有正确更新数据源。最后data['y'].push(deaths) 的操作实际上使死亡列表成为现有空列表的子列表,这不是正确的格式。这是JS代码的更新版本:

    const rdataYear = rect.YEAR
    const rdataAgeGroup = rect.AGE_GROUP
    const rdataDeaths = rect.DEATHS
    const years = [1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017]
    
    const indices = cb_data.index.indices;
    const newarr = rect.AGE_GROUP.map((e,i) => e === rdataAgeGroup[indices] ? i : undefined).filter(x => x);
    
    const deaths = []
    for (var i = 0; i < newarr.length; i++){
        deaths.push(rdataDeaths[newarr[i]])
    }
    
    line.data = {x: years, y: deaths}
    

    请注意,如果您实际分配给 .data,则 Bokeh 可以自动检测到,无需显式信号。

    【讨论】:

    猜你喜欢
    • 2021-09-29
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 1970-01-01
    相关资源
    最近更新 更多