简体   繁体   English

当在Bokeh中更改链接到另一个图形的另一个图形的x_range时,更改图形中的绘制数据

[英]Change plotted data in a figure when x_range of another figure linked to the other one is changed in Bokeh

I have two figures in which data source is linked in Bokeh. 我有两个图,其中的数据源是在Bokeh中链接的。 The left figure show (x, y) and the right figure shows (v, z) and the other shows (x, y). 左图显示(x,y),右图显示(v,z),其他图显示(x,y)。 I want to re-draw the left figure when the x_range of the right figure is changed so that the data points not shown in the right panel are removed from the left panel. 我想在更改右图的x_range时重新绘制左图,以便从左面板中删除未在右面板中显示的数据点。 I thought I should use a callback feature of Bokeh, but I'm not familiar with it. 我以为我应该使用Bokeh的回调功能,但我对此并不熟悉。 I tried to write the following code, but it does not work. 我试图编写以下代码,但是它不起作用。 It would be great if someone tell me how to do it. 如果有人告诉我该怎么做,那就太好了。

import numpy as np

from bokeh.io import output_notebook, show, save, output_file
from bokeh.models import ColumnDataSource, HoverTool, CustomJS
from bokeh.models.formatters import DatetimeTickFormatter
from bokeh.palettes import brewer, all_palettes, viridis
from bokeh.plotting import figure
from bokeh.models import WMTSTileSource
from bokeh.layouts import column, row, gridplot

x = np.random.randn(100)
y = np.random.randn(100)
z = x**2
v = np.exp(-0.5 * x**2)
colors = np.array(viridis(x.size))

source_all = ColumnDataSource(
    data=dict(x=x,
              y=y,
              z=z,
              v=v,
              colors=colors,
              index=np.arange(x.size, dtype=np.int)))

source_plot = ColumnDataSource(
    data=dict(x=x,
              y=y,
              z=z,
              v=v,
              colors=colors))

left = figure(plot_width=300, plot_height=300, title=None, 
              x_range=(-3, 3),
              y_range=(-3, 3),
             tools=['reset', 'save', 'pan', 'wheel_zoom', 'tap', 'box_select'])
left.circle('x', 'y', source=source_plot, color='colors')

right = figure(plot_width=300, plot_height=300, title=None, # x_range=(),
              tools=['reset', 'save', 'pan', 'wheel_zoom', 'tap', 'box_select'])
right.circle('v', 'z', source=source_plot, color='colors')

def callback(left=left, right=right, source=source_plot, source_all=source_all, window=None):

    x_range = right.x_range
    x_range.have_updated_interactively = False

    xmin = x_range[0]
    xmax = x_range[1]

    data = source.data
    data_all = source_all.data

    x, y, z, v, color = data['x'], data['y'], data['z'], data['v'], data['colors']
    xa, ya, za, va, colora = data_all['x'], data_all['y'], data_all['z'], data_all['v'], data_all['colors']

    for i in range(len(v)):
        if v[i] < xmin or v[i] > xmax:
            x[i] = np.nan
            y[i] = np.nan
            z[i] = np.nan
            color[i] = None
        else:
            x[i] = xa[i]
            y[i] = ya[i]
            z[i] = za[i]
            color[i] = colora[i]
    Bokeh.index[left.id].plot_canvas_view.update_dataranges()
    source.change.emit()

callback = CustomJS.from_py_func(callback)


right.x_range.js_on_change('start', callback)

p = gridplot([[left, right]])

show(p)

You could work that with a callback but isn't a lasso_select or box_select doing more or less what you want? 您可以通过回调进行操作,但是lasso_select或box_select不能或多或少地执行您想要的操作吗? 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM