使用Bokeh回调根据选择更新图像

时间:2019-10-30 16:14:19

标签: python data-visualization bokeh

我正在使用Bokeh显示散点图和图像。我想根据散点图中选择的点更新图像。我正在使用JavaScript回调进行此操作,但似乎没有效果。

我有一个散点图p1,其中每个观测值都存储在s1中,并且具有(x,y)坐标以及相关的图像:

from bokeh.io import show, output_notebook
from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.plotting import figure
output_notebook()
x = [0, 1, 2]
y = [abs(xx) for xx in x]
img = [[[1, 0], [1, 0]], [[1, 1], [1, 0]], [[1, 0], [1, 0]]]

s1 = ColumnDataSource(data=dict(x=x, y=y, i=img))
# Scatter plot on which point should be selected
p1 = figure(
    tools='lasso_select', plot_width=600, plot_height=600, 
    title="A few points to select"
)
p1.circle('x', 'y', source=s1)

目标是让另一个图p2显示一个图像,该图像是s1中选定点的所有图像的平均值。我使用第二个来源s2存储此平均图像:

# s2 is initialised with an empty image
s2 = ColumnDataSource(
    data=dict(avg=[[[0, 0], [0, 0]]], 
    xmin=[0], ymin=[0], dw=[2], dh=[2])
)
# Image which should change based on selection in p1
p2 = figure(title="Image affected by selection", plot_width=300,
    plot_height=300, x_range = [0, 2], y_range = [0, 2]
)
p2.image(image="avg", x="xmin", y="ymin",
    dw="dw", dh="dh", palette="Spectral11", source=s2
)

我想使用JS回调更新此平均值,以根据s1中选择的索引更新s2

# Update s2 based on data selected in s1
s1.selected.js_on_change('indices', CustomJS(args=dict(s1=s1, s2=s2), code="""
        var inds = cb_obj.indices;
        var d1 = s1.data;
        var d2 = s2.data;
        var cmat = new Array(2);
        for (var i = 0; i < cmat.length; i++) {
          cmat[i] = new Array(2);
        }
        for (x=0; x < 2; x++){
          for (y=0; y < 2; y++){
            for (i=0; i < inds.length; i++){
              cmat[x][y] = d1['img'][inds[i]][x][y]
            }
          }
          cmat[x][y] /= inds.length
        }
        d2['avg'] = []
        d2['avg'].push(cmat);
        d2.change.emit();
    """))

p = gridplot([[p1, p2]])
show(p)

但是,回调似乎没有任何作用。我以前成功地使用了回调来影响散点图上的显示,但无法使其与图像一起使用。

当我选择点时,图像保持空白。是否有一种在JS回调中操纵数组的好方法,还是我应该以其他方式进行处理?

1

0 个答案:

没有答案