javascript - Bokeh 服务器获取鼠标位置

标签 javascript python bokeh

我正在开发一个带有 Bokeh (0.12.2) 的交互式应用程序,它可以根据特定的交互更新绘图。

现在我使用 slider 来更改图形中字形的位置,但实际上我想访问我的鼠标在特定图形中的位置。

数据集是一个多维矩阵(张量),密集的数据,每个图在特定位置显示一个维度。如果我更改标记符号在一个图上的位置,则其他图也需要更新,这意味着我必须根据更新后的位置对数据集进行切片。

这是一个简单的示例,我尝试使用悬停工具在我的 Bokeh 服务器更新功能中获取鼠标数据:

from bokeh.plotting import figure, ColumnDataSource
from bokeh.models import CustomJS, HoverTool
from bokeh.io import curdoc

s = ColumnDataSource(data=dict(x=[0, 1], y=[0, 1]))
callback = CustomJS(args=dict(s=s), code="""
        var geometry = cb_data['geometry'];
        var mouse_x = geometry.x;
        var mouse_y = geometry.y;
        var x = s.get('data')['x'];
        var y = s.get('data')['y'];
        x[0] = mouse_x;
        y[0] = mouse_y;
        s.trigger('change');
    """)
hover_tool = HoverTool(callback=callback)
p = figure(x_range=(0, 1), y_range=(0, 1), tools=[hover_tool])
p.circle(x='x', y='y', source=s)


def update():
    print s.data

curdoc().add_root(p)
curdoc().add_periodic_callback(update, 1000)

不幸的是,服务器只输出:

{'y': [0, 1], 'x': [0, 1]}

{'y': [0, 1], 'x': [0, 1]}

{'y': [0, 1], 'x': [0, 1]}

{'y': [0, 1], 'x': [0, 1]}

有没有办法访问鼠标位置(在 python 代码中)?甚至访问字形的位置就足够了(因为我可以使用一些 javascript 代码更改字形的位置)。


编辑:所以我最近发现我可以使用这个tool_events.on_change() 来达到这个目的。不幸的是,它只适用于 TapToolLassoSelectToolBoxSelectTool,不适用于 HoverTool:

from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.models.tools import BoxSelectTool, TapTool, HoverTool, LassoSelectTool
from bokeh.models.ranges import Range1d

TOOLS = [TapTool(), LassoSelectTool(), BoxSelectTool(), HoverTool()]
p = figure(tools=TOOLS,
           x_range=Range1d(start=0.0, end=10.0),
           y_range=Range1d(start=0.0, end=10.0))

def tool_events_callback(attr, old, new):
    print attr, 'callback', new

p.tool_events.on_change('geometries', tool_events_callback)
curdoc().add_root(p)

基于我在这里找到的答案:How can I get data from a ColumnDataSource object which is synchronized with local variables of Bokeh's CustomJS function? .此解决方案的问题是我无法使用平移并触发 tool_events 回调。我只能单击 (TapTool) 或平移并仅触发一次回调 (Lasso/BoxSelectTool)。我实际上希望在每次鼠标移动时触发这样的回调..

最佳答案

所以我最近发现您可以为此目的使用自定义模型。这意味着,扩展现有工具,例如GestureTool 但实现/覆盖您自己的功能。您需要运行 Bokeh 服务器(显然)。

$ bokeh serve dir_with_mainfile/

我现在使用的是: 创建文件 MouseMoveTool.py:

from bokeh.models import Tool
class MouseMoveTool(Tool):
    # assuming your models are saved in subdirectory models/
    with open('models/MouseMoveTool.coffee', 'r') as f:
        controls = f.read()
    __implementation__ = controls

然后创建 MouseMoveTool.coffee:

p = require "core/properties"
GestureTool = require "models/tools/gestures/gesture_tool"

class MouseMoveToolView extends GestureTool.View
     ### Override the _pan function ###
     _pan: (e) ->
        frame = @plot_model.frame
        canvas = @plot_view.canvas

        vx = canvas.sx_to_vx(e.bokeh.sx)
        vy = canvas.sy_to_vy(e.bokeh.sy)
        if not frame.contains(vx, vy)
            return null

        # x and y are your mouse coordinates relative to the axes values
        x = frame.x_mappers.default.map_from_target(vx)
        y = frame.y_mappers.default.map_from_target(vy)

        # update the model's geometry attribute. this will trigger
        # the tool_events.on_change('geometries', ..) callback
        # in your python code.
        @plot_model.plot.tool_events.geometries = [{x:x, y:y}]

class MouseMoveTool extends GestureTool.Model
    default_view: MouseMoveToolView
    type: "MouseMoveTool"

    tool_name: "Mouse Move Tool"
    icon: "bk-tool-icon-pan"
    event_type: "pan"
    default_order: 13

module.exports =
    Model: MouseMoveTool
    View: MouseMoveToolView

之后,您可以在 main.py 程序中使用您的工具:

from models.MouseMoveTool import MouseMoveTool
p = figure(plot_width=300, plot_height=300, tools=[MouseMoveTool()])
p.tool_events.on_change('geometries', on_mouse_move)

def on_mouse_move(attr, old, new):
    print new[0] # will print {x:.., y:..} coordinates

关于javascript - Bokeh 服务器获取鼠标位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39744122/

相关文章:

javascript - Dart : capture an image of a Flutter webview

python - Pandas :连接文件但跳过第一个文件以外的标题

python - 在集合字典中将具有相同值的所有键分组

python - Docker 身份验证中的 Flask + Bokeh

Bokeh 服务正在运行但无法使用浏览器访问

javascript - Angular 输入指令在 IE8 和 IE9 中无法按预期工作

javascript - 将多个选择字段值组合成一个变量

javascript - Highchart 不显示 unicode 字符

python - Scikit-Learn 决策树 : Probability of prediction being a or b?

python - 将工具提示添加到 Bokeh DataTable