如何说服 visuals_at 超越 ViewBox?

How to persuade visuals_at to look beyond ViewBox?

我目前正在评估 vispy 是否满足我的交互式绘图需求。虽然感觉有点像测试版,但我对它的速度印象深刻。另外 API 设计方面它看起来很有前途。

我需要使用的一项功能是使用鼠标选取绘图元素。发行版 (0.6.4) 中有一个示例承诺做到这一点:examples/demo/scene/picking.py。不幸的是,它对我不起作用。

它显示单个 window,其中包含一个多线图。我可以与整个情节互动,即缩放和移动,但我不能 select 单独的线条。

如果我猴子调试相关代码(打印语句是我的,完整示例是 at github):

@fig.connect
def on_mouse_press(event):
    global selected, fig
    if event.handled or event.button != 1:
        return
    if selected is not None:
        selected.set_data(width=1)
    selected = None
    for v in fig.visuals_at(event.pos):
        print(v)
        if isinstance(v, vp.LinePlot):
            selected = v
            break
    if selected is not None:
        selected.set_data(width=3)
        update_cursor(event.pos)

无论我点击哪里,我都会得到 <ViewBox at 0x...>fig 是一个 vispy.plot.Fig 实例,它是 not well documented.

我怎样才能完成这项工作,即让 visuals_at 超越 ViewBox 并找到实际的 LinePlot 个实例?

有一种解决方法可以在调用 visuals_at 之前使视图成为非交互视图。 之后视图可以再次设置为交互式。

可以在 google 组消息中找到此解决方法 workaround

post 是 2015 年的,所以这个问题似乎已经知道有一段时间了。

代码

所以加入代码

plt.view.interactive = False

在调用 fig.visuals_at 之前和之后做

plt.view.interactive = True

之后 on_mouse_press 的代码应该如下所示:

def on_mouse_press(event):
    global selected, fig
    if event.handled or event.button != 1:
        return
    if selected is not None:
        selected.set_data(width=1)
    selected = None
    plt.view.interactive = False
    for v in fig.visuals_at(event.pos):
        if isinstance(v, vp.LinePlot):
            selected = v
            break
    plt.view.interactive = True
    if selected is not None:
        selected.set_data(width=3)
        update_cursor(event.pos)

测试