1

是否可以使用js_on_changewithbokeh动态更新放置在绘图旁边的文本?

例如,使用来自不同问题的此代码段


from random import random
from bokeh.models import CustomJS, ColumnDataSource, Span
from bokeh.plotting import figure, output_file, show

output_file("callback.html")

x = [random() for x in range(500)]
y = [random() for y in range(500)]
color = ["navy"] * len(x)

s = ColumnDataSource(data=dict(x=x, y=y, color=color))
p = figure(plot_width=400,
           plot_height=400,
           tools="lasso_select",
           title="Select Here")
p.circle(x='x', y='y', color='color', size=8, source=s, alpha=0.4)

slope = Span(location=.5,
             dimension="width",
             line_alpha=.6,
             line_width=5)
p.add_layout(slope)

s.selected.js_on_change(
    'indices',
    CustomJS(args=dict(s=s, slope=slope),
             code="""       
        var inds = cb_obj.indices;
        
        if (inds.length == 0) {
            slope.location = 0.5
            return 
        }
        
        var total = 0;
        for (var i = 0; i < inds.length; i++) {
            total += s.data["y"][inds[i]]
        }
        var avg = total / inds.length;
        slope.location = avg;
    """))

show(p)

我想在图形右侧包含一个文本,显示计算的值,slope.location并在我选择新点时更新。

4

1 回答 1

1

您可以使用类似的文本小部件PreText,将其放置在绘图的右侧,例如通过layout.text并在您的 JSCallback 中更新该小部件的属性。确保使用.toString()方法来分配值。

from random import random
from bokeh.models import CustomJS, ColumnDataSource, Span, PreText
from bokeh.plotting import figure, output_file, show
from bokeh.layouts import layout

output_file("callback.html")

x = [random() for x in range(500)]
y = [random() for y in range(500)]
color = ["navy"] * len(x)

s = ColumnDataSource(data=dict(x=x, y=y, color=color))
p = figure(plot_width=400,
           plot_height=400,
           tools="lasso_select",
           title="Select Here")
p.circle(x='x', y='y', color='color', size=8, source=s, alpha=0.4)

slope = Span(location=.5,
             dimension="width",
             line_alpha=.6,
             line_width=5)
p.add_layout(slope)

slope_text = PreText(text='Slope_Text')

s.selected.js_on_change(
    'indices',
    CustomJS(args=dict(s=s, slope=slope, slope_text=slope_text),
             code="""       
        var inds = cb_obj.indices;
        
        if (inds.length == 0) {
            slope.location = 0.5
            return 
        }
        
        var total = 0;
        for (var i = 0; i < inds.length; i++) {
            total += s.data["y"][inds[i]]
        }
        var avg = total / inds.length;
        slope.location = avg;
        slope_text.text = avg.toString();
    """))

layout_ = layout([[p,slope_text]])
show(layout_)
于 2021-03-23T12:25:26.837 回答