我是Bokeh for Python这个极好的工具的新手。我使用Python 2.7和Bokeh 0.10。
我正在尝试做一个基本情节:
我尝试了很多东西,结果喜忧参半。
import numpy as np
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, Circle, HoverTool, CustomJS
output_file("callback.html")
#data definition
x = np.arange(100)
y = 20 + 10 * np.random.uniform(size = 100)
y2 = 20 + 10 * np.random.uniform(size = 100)
label1 = np.arange(100)
#sources creation
source = ColumnDataSource(
data=dict(
x=x,
y=y,
label = label1
)
)
source2 = ColumnDataSource(
data=dict(
x=x,
y=y2,
label = label1
)
)
hover = HoverTool(
tooltips=[
("label", "@label")
]
)
p = figure(plot_width=800, plot_height=800, tools=[hover,'box_zoom,resize,wheel_zoom,reset'],
title="Mouse over the dots")
circle1 = Circle(x='x', y='y', radius=20, fill_color='red',fill_alpha = 1)
circle2 = Circle(x='x', y='y2', radius=20,fill_color = 'green',fill_alpha = 1)
circle1_grey = Circle(x='x', y='y', radius=2, fill_color='red',fill_alpha = 0.2)
circle2_grey = Circle(x='x', y='y', radius=2, fill_color='green',fill_alpha = 0.2)
cr = p.add_glyph(source, circle1_grey, selection_glyph=circle1, nonselection_glyph=circle1_grey)
cr2 = p.add_glyph(source2, circle2_grey, selection_glyph=circle2, nonselection_glyph=circle2_grey)
callback = CustomJS(args={'sourceA': source, 'sourceB' : source2}, code="""
var dataA = sourceA.get('data');
var dataB = sourceB.get('data');
var f = cb_data['index'];
sourceA.set('selected', f);
sourceB.set('selected', f);
sourceA.trigger('change');
sourceB.trigger('change');
""")
p.add_tools(HoverTool(tooltips=None, callback=callback, renderers=[cr,cr2], mode='vline'))
show(p)
通过这个解决方案,有几点让我不高兴:
除了这些问题,我对Bokeh非常满意!非常感谢开发这个库和&像我这样的帮助。
吨。
答案 0 :(得分:0)
现在解决方案就是这样的。但我认为
# [...]
hover_init_data = {
'x': [],
'y': []
}
self.hover_source = ColumnDataSource(data=hover_init_data)
# these are the bigger circles
c = self.plot.circle(
x='x',
y='y',
size=10,
fill_color='black',
line_color=None,
source=self.hover_source,
)
c.selection_glyph = Circle(
fill_color='black',
)
c.nonselection_glyph = Circle(
fill_color='black',
)
hover_callback = CustomJS(
args={'source': self.source, 'hover_source' : self.hover_source},
code='''
console.log(cb_data);
var inds = cb_data['index'].indices;
console.log(inds);
var s = source.data;
var h = hover_source.data;
h['x'] = []
h['y'] = []
for (i = 0; i < inds.length; i++) { // You can limit the number of overlapped points here
h['x'].push(s['x'][inds[i]])
h['y'].push(s['y'][inds[i]])
}
hover_source.change.emit();
''',
)
hover = HoverTool(
callback=hover_callback,
renderers=[main_circle_renderer], // if there are more than one renderer the callback is not triggered
tooltips="""
<b>x: </b> @x <br>
<b>y: </b> @y <br>
""",
)
# [...]
注意:同时检查此old issue,还有待改进