javascript - Bokeh :在悬停回调中更改圆圈大小

标签 javascript python python-3.x hover bokeh

我是 Python 版 Bokeh 这个出色工具的新手。我使用 Python 2.7 和 Bokeh 0.10。

我正在尝试做一个基本情节:

  • 两个数据系列
  • '同时悬停':横坐标相同的两个系列点都在显示一些东西
  • 将鼠标悬停在上面时,两个选定的点会突出显示:它们变大,另一个的 fill_alpha 变为 0.2

我尝试了很多东西,结果好坏参半。

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)

对于这个解决方案,有几点让我不满意:

  • 选中时圆圈不会变大。我试图在回调中做到这一点,但我也没有做对。
  • 缩放时,点变得太大并开始重叠。要解决这个问题,使用“size = 20”是可行的,但随后“mode=vline”开始失败:悬停太粗并且总是选择几个点。我尝试混合使用 size=20 和 radius = 2,但它也不起作用。
  • 我没能添加图例(但我可以自己添加)。

除了这些问题,我对 Bokeh 非常满意!非常感谢开发这个库并帮助像我这样的菜鸟。

最佳答案

现在的解决方案是这样的。但我认为

# [...]

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此外,还有几项待改进

关于javascript - Bokeh :在悬停回调中更改圆圈大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32989204/

相关文章:

javascript - 检查复选框是否被选中(js/jquery)

javascript - 我想知道如何在服务器上的 HTML 文档中执行 JS

python - 成对组合来自两个数组的元素

python - 如何创建一个循环,每行打印列表的 6 个元素?

python - 使用 pyodbc 连接到 Oracle 数据库

python - 有没有办法 "work around"装饰器的保留状态?

javascript - 每次输入更改时提交表单的最佳实践

django - 如何使用 ChannelNameRouter 在 Worker 和 Websocket(Django 和 Channels2.x)之间进行通信?

python - 在 Python 列表中查找 "x"最大差异

javascript - 如何使用nock记录对文件的请求和响应并在mocha验收测试中使用它进行播放?