我有三维x,y和z的数据 . 我将它们显示为散景网格图,其中三个单独的图形彼此相同 . x轴是链接的,这样如果我在其中一个图形中平移,其他图形将被更新:

time = np.arange(len(data))

labels = ["x","y","z"]
plots = []

for i in range(3):
    if i != 0:
        fig = figure(plot_width=900, plot_height=150, x_range=first.x_range)
    else:
        fig = figure(plot_width=900, plot_height=150)
        # First figure is saved as other figures are linked to this one
        first = fig

    source = ColumnDataSource({'x': time, 'y': data[:,i]})
    fig.line('x','y', source=source)

    fig.yaxis.axis_label = labels[i]
    plots.append([fig])

p = gridplot(([plots[0], plots[1], plots[2]]))
show(p)

我还实现了x轴范围的回调,每次x范围变化时都会更新图形,以便绘图填充y轴上的完整图形:

fig.x_range.callback = CustomJS(args=dict(source=source, xrange=fig.x_range,
                                yrange=fig.y_range), code=adjust_y_range_js)

在此代码中,范围对象使用新计算的范围进行设置,这会触发源自回调的图形中的更新 . 即如果我放大三个图形中的第一个图形,第一个图形的y范围将被更新,以便填充图形 . 由于与其他图的联系,其他两个图的x范围也将改变 . 但是,它们的x_ranges不会触发回调 . 我尝试在回调JS代码中传递其他范围并以下列方式更新它们,但未成功:

xrange_other.trigger('change');

这将使盒子选择工具由于某种原因而冻结,即它将永久地尝试进行选择 . 任何想法如何以另一种方式更新整个情节?

回调的代码如下(取自某人的github,但遗憾的是找不到原始来源):

adjust_y_range_js = """
function isNumeric(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

var data = source.get('data');
var start = yrange.get('start');
var end = yrange.get('end');

var time_start = xrange.get('start');
var time_end = xrange.get('end');

var pre_max_old = end;
var pre_min_old = start;

var time = data['x'];
var pre = data['y'];
t_idx_start = time.filter(function(st){return st>=time_start})[0];
t_idx_start = time.indexOf(t_idx_start);

t_idx_end = time.filter(function(st){return st>=time_end})[0];
t_idx_end = time.indexOf(t_idx_end);

var pre_interval = pre.slice(t_idx_start, t_idx_end);
pre_interval = pre_interval.filter(function(st){return !isNaN(st)});
var pre_max = Math.max.apply(null, pre_interval);
var pre_min = Math.min.apply(null, pre_interval);
var ten_percent = (pre_max-pre_min)*0.1;

pre_max = pre_max + ten_percent;
pre_min = pre_min - ten_percent;
if((!isNumeric(pre_max)) || (!isNumeric(pre_min))) {
    pre_max = pre_max_old;
    pre_min = pre_min_old;
}

yrange.set('start', pre_min);
yrange.set('end', pre_max);


// This is what I tried. When using these variables, I passed them in the CustomJS args dict, of course.
//yrange_other1.trigger('change');
//yrange_other2.trigger('change');
//xrange_other1.trigger('change');
//xrange_other2.trigger('change');
//soure_other1.trigger('change');
//soure_other2.trigger('change');
"""

我使用的是python 2.7.10和Bokeh版本0.12.3 .