我正在使用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回调中操纵数组的好方法,还是我应该以其他方式进行处理?