可以'不要让Bokeh中的CrossHairTool链接到几个绘图上



我研究过这个帖子:

"如何将散焦中的CrossHairTool链接到多个图上"(请参阅如何在多个绘图上链接散焦中的CrossHairTool?.

我在这篇文章中使用了Hamid Fadishei于2020年6月编写的函数,但无法使CrossHairTool在多个图中正确显示。

在我的实现中,十字线只显示在悬停的绘图中。我目前使用Bokeh版本2.1.1和Python Anaconda版本3.7.6,使用VSCode版本1.48中的Python扩展。我不熟悉Javascript,所以任何帮助调试我的代码以正确显示两个图中的十字线的方法都将受到欢迎。

我的代码:

# Importing libraries:
import pandas as pd
import random
from datetime import datetime, timedelta
from bokeh.models import CustomJS, CrosshairTool, ColumnDataSource, DatetimeTickFormatter, HoverTool
from bokeh.layouts import gridplot
from bokeh.plotting import figure, output_file, show
# Function wrote by Hamid Fadishei to enable a linked crosshair within gridplot:
def add_vlinked_crosshairs(figs):
js_leave = ''
js_move = 'if(cb_obj.x >= fig.x_range.start && cb_obj.x <= fig.x_range.end &&n'
js_move += 'cb_obj.y >= fig.y_range.start && cb_obj.y <= fig.y_range.end){n'
for i in range(len(figs)-1):
js_move += 'tttother%d.spans.height.computed_location = cb_obj.sxn' % i
js_move += '}else{n'
for i in range(len(figs)-1):
js_move += 'tttother%d.spans.height.computed_location = nulln' % i
js_leave += 'tttother%d.spans.height.computed_location = nulln' % i
js_move += '}'
crosses = [CrosshairTool() for fig in figs]
for i, fig in enumerate(figs):
fig.add_tools(crosses[i])
args = {'fig': fig}
k = 0
for j in range(len(figs)):
if i != j:
args['other%d'%k] = crosses[j]
k += 1
fig.js_on_event('mousemove', CustomJS(args=args, code=js_move))
fig.js_on_event('mouseleave', CustomJS(args=args, code=js_leave))
# Create dataframe consisting of 5 random numbers within column A and B as a function of an arbitrary time range:
startDate = datetime(2020,5,1)
timeStep = timedelta(minutes = 5)
df = pd.DataFrame({
"Date": [startDate  + (i * timeStep) for i in range(5)],
"A": [random.randrange(1, 50, 1) for i in range(5)],
"B": [random.randrange(1, 50, 1) for i in range(5)]})
# Generate output file as html file:
output_file("test_linked_crosshair.html", title='Results')
# Define selection tools within gridplot:
select_tools = ["xpan", "xwheel_zoom", "box_zoom", "reset", "save"]
sample = ColumnDataSource(df)
# Define figures:
fig_1 = figure(plot_height=250,
plot_width=800,
x_axis_type="datetime",
x_axis_label='Time',
y_axis_label='A',
toolbar_location='right',
tools=select_tools)
fig_1.line(x='Date', y='A',
source=sample,
color='blue',
line_width=1)
fig_2 = figure(plot_height=250,
plot_width=800,
x_range=fig_1.x_range,
x_axis_type="datetime",
x_axis_label='Time',
y_axis_label='B',
toolbar_location='right',
tools=select_tools)
fig_2.line(x='Date', y='B',
source=sample,
color='red',
line_width=1)
# Define hover tool for showing timestep and value of crosshair on graph:
fig_1.add_tools(HoverTool(tooltips=[('','@Date{%F,%H:%M}'),
('','@A{0.00 a}')],
formatters={'@Date':'datetime'},mode='vline'))
fig_2.add_tools(HoverTool(tooltips=[('','@Date{%F,%H:%M}'),
('','@B{0.00 a}')],
formatters={'@Date':'datetime'},mode='vline'))
# Calling function to enable linked crosshairs within gridplot:
add_vlinked_crosshairs([fig_1, fig_2])
# Generate gridplot:
p = gridplot([[fig_1], [fig_2]])
show(p)

myGraphenter code here

这里有一个适用于Bokeh 2.2.1的解决方案:只需对所有需要链接的绘图使用相同的十字线工具对象。像这样:

import numpy as np
from bokeh.plotting import figure, show
from bokeh.layouts import gridplot
from bokeh.models import CrosshairTool
plots = [figure() for i in range(6)]
[plot.line(np.arange(10), np.random.random(10)) for plot in plots]
linked_crosshair = CrosshairTool(dimensions="both")
for plot in plots:
plot.add_tools(linked_crosshair)
show(gridplot(children=[plot for plot in plots], ncols=3))

最新更新