4

我目前正在评估vispy我的交互式绘图需求。虽然它感觉有点像测试版,但我对它的速度印象深刻。从 API 设计的角度来看,它看起来很有希望。

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

它显示一个包含多条线图的窗口。我可以与整个情节进行交互,即缩放和移动,但我不能选择单独的线条。

如果我对相关的代码进行猴子调试(打印语句是我的,完整的例子在 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的实例。

我怎样才能使这项工作,即visuals_at超越ViewBox并找到实际LinePlot实例?

4

1 回答 1

1

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

可以在 google groups message workaround中找到此解决方法

该帖子来自 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)

测试

测试输出

于 2020-03-13T22:27:42.597 回答