【问题标题】:bokeh - plot a different column using customJS散景 - 使用 customJS 绘制不同的列
【发布时间】:2018-02-27 02:17:35
【问题描述】:

我有一个多列的数据框。前两列是 x 和 y 坐标,其余列是 (x,y) 对的不同属性值。

import pandas as pd
import numpy as np
df = pd.DataFrame()
df['x'] = np.random.randint(1,1000,100)
df['y'] = np.random.randint(1,1000,100)
df['val1'] = np.random.randint(1,1000,100)
df['val2'] = np.random.randint(1,1000,100)
df['val3'] = np.random.randint(1,1000,100)

print df.head()

     x    y  val1  val2  val3
0  337  794   449   969   933
1   19  563   592   677   886
2  512  467   664   160    16
3   36  112    91   230   910
4  972  572   336   879   860

在 Bokeh 中使用 customJS,我想通过提供下拉菜单来更改二维热图中的颜色值。

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
from bokeh.models import LinearColorMapper
from bokeh.palettes import RdYlBu11 as palette

p = figure()
source =   ColumnDataSource(df)
color_mapper = LinearColorMapper(palette=palette)
p.patches('x', 'y', source=source,\
          fill_color={'field': 'val1', 'transform':color_mapper})

show(p)

上述命令绘制了一个颜色图,其颜色由列 'val1' 确定。我想根据下拉菜单中选择的内容绘制不同的列(val1、val2 或 val3)。

我可以在散景中创建一个下拉小部件

 from bokeh.models.widgets import Select
 select = Select(title="Option:", value="val1", options=["val1","val2","val3"])

但是,我不太确定如何使用选定的值通过回调来更新绘图。

有人可以在这里给我一个指导吗?

谢谢。

【问题讨论】:

    标签: python bokeh


    【解决方案1】:

    我在代码中包含了一个内联 cmets 的示例。主要的重要步骤是编写每次在小部件上选择的选项更改时执行的 javascript 代码。代码只需要重新分配哪些列设置为数据源的“y”列的值。

    另一个问题是您的数据只是 x 和 y 点。补丁字形将需要一个不同的数据结构来定义补丁的边界。我相信在散景中制作热图有更好的方法,应该有很多关于堆栈溢出和散景文档的示例。

    import pandas as pd
    import numpy as np
    
    from bokeh.io import show
    from bokeh.layouts import widgetbox,row
    from bokeh.models import ColumnDataSource, CustomJS
    
    df = pd.DataFrame()
    df['x'] = np.random.randint(1,1000,1000)
    df['y'] = np.random.randint(1,1000,1000)
    df['val1'] = np.random.randint(1,1000,1000)
    df['val2'] = np.random.randint(1,1000,1000)
    df['val3'] = np.random.randint(1,1000,1000)
    
    from bokeh.plotting import figure
    from bokeh.models import LinearColorMapper
    from bokeh.palettes import RdYlBu11 as palette
    
    p = figure(x_range=(0,1000),y_range=(0,1000))
    source = ColumnDataSource(df)
    source_orig = ColumnDataSource(df)
    color_mapper = LinearColorMapper(palette=palette)
    p.rect('x', 'y', source=source,width=4,height=4,
              color={'field': 'val1', 'transform':color_mapper})
    
    from bokeh.models.widgets import Select
    select = Select(title="Option:", value="val1", options=["val1","val2","val3"])
    
    callback = CustomJS(args={'source':source},code="""
            // print the selectd value of the select widget - 
            // this is printed in the browser console.
            // cb_obj is the callback object, in this case the select 
            // widget. cb_obj.value is the selected value.
            console.log(' changed selected option', cb_obj.value);
    
            // create a new variable for the data of the column data source
            // this is linked to the plot
            var data = source.data;
    
            // allocate the selected column to the field for the y values
            data['y'] = data[cb_obj.value];
    
            // register the change - this is required to process the change in 
            // the y values
            source.change.emit();
    """)
    
    # Add the callback to the select widget. 
    # This executes each time the selected option changes
    select.callback = callback
    show(row(p,select))
    

    【讨论】:

    • 感谢您的快速回答。你能解释一下为什么你更新'y'吗?这不是数据框df中的y坐标值吗?
    • 在你的问题中你说你想绘制不同的列,所以我只是更新了 y 作为演示。您显然可以更新 x 或 y。如果您的意图是更新更改色阶的列,我将创建一个单独的列,然后在有意义的情况下更改回调中的值
    • 我明白了。这就说得通了。我试图更新字段参数值,但只是在源代码中创建一个单独的列并保持结构不变是一种方法。谢谢你。这真的很有帮助。
    • 没问题,如果已经达到您的要求,请将答案标记为正确。
    • source_orig = ColumnDataSource(df) 在您的代码中做了什么?我删除了该行,但它似乎没有改变输出?
    猜你喜欢
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 2019-07-23
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    相关资源
    最近更新 更多