【问题标题】:Bokeh, how to change column used for glyph colors with CustomJS callbacks?散景,如何使用 CustomJS 回调更改用于字形颜色的列?
【发布时间】:2022-02-15 08:08:57
【问题描述】:

我正在使用 Bokeh 通过将 ColumnDataSource 传递给 figure.circle 函数来创建散点图。数据源有为每个点指定特定颜色的列,每行都有一个十六进制代码,因为我要使用的着色方案有些复杂。

有没有办法在小部件的回调中更改用于为圆圈着色的列?我正在想象一个下拉菜单,允许用户为点选择各种着色方案。

【问题讨论】:

    标签: javascript python bokeh


    【解决方案1】:

    以下是使用models.Select 小部件和models.CustomJSFigure.circleColumnDataSource 中定义的两种配色方案中进行选择的解决方案示例:

    import bokeh
    import bokeh.plotting
    p = bokeh.plotting.figure(x_range=(0,4), y_range=(0,4), plot_height=200 )
    csource = bokeh.models.ColumnDataSource(data=dict(
            x=[1,2,3],
            y=[1,2,1],
            colors1=["#ff0000","#00ff00","#0000ff"],
            colors2=["#ff00ff","#ffff00","#00ffff"]))
    cir = p.circle(x="x",y="y",fill_color="colors1",line_color="colors1",
                   size=20,source=csource)
    cb_cselect = bokeh.models.CustomJS(args=dict(cir=cir,csource=csource), code ="""
        var selected_color = cb_obj.value;
        cir.glyph.line_color.field = selected_color;
        cir.glyph.fill_color.field = selected_color;
        csource.trigger("change")
    """)
    color_select = bokeh.models.Select(title="Select colors", value="colors1", 
                        options = ["colors1","colors2"], callback = cb_cselect)
    layout = bokeh.layouts.gridplot([[p],[color_select]])
    bokeh.io.output_file("output.html")
    bokeh.io.show(layout)
    

    输出看起来像

    【讨论】:

    • 感谢您花时间举例说明。我意识到我应该简单地在数据源中为颜色创建一个列,然后使用回调将颜色加载到其中。
    • 您是否还知道如何从 JS 回调中更改颜色条?
    • 我还没有测试颜色条功能。以前版本的 Bokeh 没有颜色条,所以我创建了一个作为第二个图,并添加了一些基于 matplotlib 地图的颜色条选择:请参阅 github.com/pmreyes2/bokeh_utils
    • ColorBar 有一个color_mapper 属性,它是ColorMapper 的一个实例。您应该能够在颜色映射器上设置palette(或任何其他)属性,并且颜色条将自行更新和重绘。
    【解决方案2】:

    我已经为 Bokeh 2.4.1 更新了出色的 answer provided by Pablo Reyes

    import bokeh
    import bokeh.plotting
    
    p = bokeh.plotting.figure(x_range=(0,4), y_range=(0,4), plot_height=200 )
    csource = bokeh.models.ColumnDataSource(data=dict(
            x=[1,2,3],
            y=[1,2,1],
            colors1=["#ff0000","#00ff00","#0000ff"],
            colors2=["#ff00ff","#ffff00","#00ffff"]))
    
    cir = p.circle(x="x",y="y",fill_color="colors1",line_color="colors1",
                   size=20,source=csource)
    
    cb_cselect = bokeh.models.CustomJS(args=dict(cir=cir,csource=csource), code ="""
        var selected_color = cb_obj.value;
        cir.glyph.line_color.field = selected_color;
        cir.glyph.fill_color.field = selected_color;
        csource.change.emit();
    """)
    
    color_select = bokeh.models.Select(title="Select colors", value="colors1", 
                        options = ["colors1","colors2"])
    
    color_select.js_on_change('value', cb_cselect)
    
    layout = bokeh.layouts.gridplot([[p],[color_select]])
    bokeh.io.output_file("output.html")
    bokeh.io.show(layout)
    

    本质上,JavaScript csource.trigger("change") 触发了 JavaScript 中的错误:

    Uncaught TypeError: csource.trigger is not a function

    将其替换为 csource.change.emit() 会产生所需的结果。虽然 source.change.emit() 没有很好的文档记录,但存在一些示例 here

    【讨论】:

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