【问题标题】:Applying .filter() to ColumnDataSource in Bokeh JS Callback在 Bokeh JS 回调中将 .filter() 应用于 ColumnDataSource
【发布时间】:2020-04-03 12:11:48
【问题描述】:

问题:我无法对 columndatasource 应用过滤器函数,即使在应用它之后也会提供我的整个完整数组。我对 JS 的不熟悉让事情变得更糟。

所以我一直试图从这里重现结果:

https://discourse.bokeh.org/t/possible-to-use-customjs-callback-from-a-button-to-animate-a-slider/3985

但是使用我自己的数据源。

这里是JS回调的代码:

# Create slider callback
SliderCallback = CustomJS(args = dict(sliceCDS=sliceCDS, fullCDS=fullCDS, indexCDS=indexCDS), code = """
    const new_value = cb_obj.value;

    // Take the 'Slice' column from the full data
    const slice_col = fullCDS.data['Slice'];

    // Select only the values equal to the new slice number
    const mask = slice_col.map((item) => item==new_value);

    sliceCDS.data['x'] = fullCDS.data['x'].filter(item => mask);
    sliceCDS.data['y'] = fullCDS.data['y'].filter(item => mask);
    sliceCDS.data['label'] = fullCDS.data['label'].filter(item => mask);

    //console.log('Here is the data');
    console.log(sliceCDS.data['x']);
    console.log(sliceCDS.data['y']);
    console.log(sliceCDS.data['label']);


    // Update the sliceCDS
    sliceCDS.change.emit();
    """)

# Set up slider
slider = bokeh.models.Slider(title="Slice view number: ",start=0, end=49,value=0,step=1)
slider.js_on_change('value', SliderCallback)

这里是 sliceCDS(JS 回调的输入):

{'x': 0   -0.001215
0    0.001454
0   -0.000191
0   -0.000377
0   -0.000008
       ...   
0    0.001993
0    0.002045
0    0.002220
0   -0.003160
0   -0.000088
Name: x, Length: 1797, dtype: float64, 'y': 0    0.000745
0    0.000171
0   -0.000004
0    0.000268
0    0.000535
       ...   
0   -0.000417
0    0.002719
0   -0.000269
0    0.000766
0    0.000250
Name: y, Length: 1797, dtype: float64, 'label': 0    0
0    0
0    0
0    0
0    0
    ..
0    9
0    9
0    9
0    9
0    9
Name: label, Length: 1797, dtype: int64, 'Slice': 0    0
0    0
0    0
0    0
0    0
    ..
0    0
0    0
0    0
0    0
0    0
Name: Slice, Length: 1797, dtype: int64}

这里是fullCDS(输入到JS回调):

{'x': 0     -0.001215
0      0.001454
0     -0.000191
0     -0.000377
0     -0.000008
        ...    
49   -12.208837
49   -11.620906
49   -16.709465
49   -13.481855
49   -12.067336
Name: x, Length: 89850, dtype: float64, 'y': 0      0.000745
0      0.000171
0     -0.000004
0      0.000268
0      0.000535
        ...    
49    28.264780
49    27.768742
49    27.019316
49    27.537040
49    24.889742
Name: y, Length: 89850, dtype: float64, 'label': 0     0
0     0
0     0
0     0
0     0
     ..
49    9
49    9
49    9
49    9
49    9
Name: label, Length: 89850, dtype: int64, 'Slice': 0      0
0      0
0      0
0      0
0      0
      ..
49    49
49    49
49    49
49    49
49    49
Name: Slice, Length: 89850, dtype: int64}

使用上面的代码,我无法更新我的 sliceCDS。它仍然包含所有 89850 行,而在应用 .filter() 后它应该只包含 1797 行。 编辑:根据建议,我还在函数中尝试了以下内容:

sliceCDS.data['x'] = fullCDS.data['x'].filter((item,idx) => mask[idx]);

它给了我以下错误:

VM499:17 Uncaught TypeError: Cannot read property 'filter' of undefined

也尝试过:

sliceCDS.data['x'] = fullCDS.data['x'].filter((item,0) => mask[0]);

这给了我这个错误:

VM505:31 Uncaught SyntaxError: Invalid destructuring assignment target

但是,如果我尝试上面给出的链接中的方法,我的 columndatasources 中的列名称为 Line1 代表 x,Line2 代表 y,Line3 代表标签:

// Update the data for sliceCDS with a slice of data from fullCDS
    for(i=1; i<3; i++){
        sliceCDS.data['Line' + i.toString()] = fullCDS.data['Line' + i.toString()].filter((item,i) => mask[i]);
    }

上面的代码运行良好。

但是为什么开头提到的案例代码不起作用?我确信我使用 .filter() 的方式有问题。

【问题讨论】:

    标签: python python-3.x bokeh bokehjs


    【解决方案1】:

    你有这个表达式。

    fullCDS.data['x'].filter(item => mask);
    

    item =&gt; mask 总是返回mask,不管item 是什么。在 JavaScript 中,无论内容如何,​​数组始终是真值。

    过滤器函数的第二个参数是项目的索引。尝试改用(item, idx) =&gt; mask[idx] lambda。

    【讨论】:

    • 嗨@Eugene,谢谢你的回复。我意识到了 MASK 部分,但是如何在这里使用 lambda 呢?例如我试过:sliceCDS.data['x'] = fullCDS.data['x'].filter((item,0) =&gt; mask[0]);,在 html 中,控制台错误显示:VM108:31 Uncaught SyntaxError: Invalid destructuring assignment target
    • 不要更改我发布的内容 - 使用 (item, idx) =&gt; mask[idx]逐字idx 是一个合适的变量,而不是你必须自己替换的东西。
    • 我也尝试过,在问题中发布了编辑。请检查一下,我在那里用错了吗?它给了我:VM499:17 Uncaught TypeError: Cannot read property 'filter' of undefined
    • 您要么设法从fullCDS.data 中删除了x 列,要么从其他地方抛出错误。如果没有完整的代码和异常的完整堆栈跟踪,我无法添加任何其他内容。
    • 很高兴听到这一切都解决了。我认为无需再突出显示该行-它已在上面的原始答案中格式化为代码。想要使用答案的人通常应该以 IMO 的任何一种方式阅读 cmets。
    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多