У меня есть две цифры, в которых источник данных связан в Боке. Левый рисунок показывает (x, y), а правый рисунок показывает (v, z), а другой показывает (x, y). Я хочу перерисовать левую фигуру, когда x_range правой фигуры изменяется так, что точки данных, не показанные на правой панели, удаляются с левой панели. Я думал, что должен использовать функцию обратного вызова Bokeh, но я не знаком с ней. Я пытался написать следующий код, но он не работает. Было бы здорово, если бы кто-нибудь сказал мне, как это сделать.
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)