Как убедить visuals_at выйти за пределы ViewBox? - PullRequest
4 голосов
/ 05 марта 2020

В настоящее время я оцениваю vispy для моих потребностей в интерактивном графике. В то время как он чувствует себя немного бета-я sh Я довольно впечатлен его скоростью. Кроме того, с точки зрения дизайна API это выглядит многообещающе.

Одна особенность, с которой мне нужно работать, это выбор элементов графика с помощью мыши. В дистрибутиве есть один пример (0.6.4), который обещает сделать именно это: examples/demo/scene/picking.py. К сожалению, это не работает для меня.

Отображает одно окно, содержащее график с несколькими строками. Я могу взаимодействовать с графиком в целом, то есть с масштабированием и смещением, но не могу выбрать отдельные строки.

Если я выполняю отладку соответствующего фрагмента кода (оператор print мой, полный пример - в 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 случаев?

1 Ответ

1 голос
/ 14 марта 2020

Существует обходной путь, чтобы сделать представление неинтерактивным перед вызовом visuals_at. После этого можно снова установить интерактивный вид.

Этот обходной путь можно найти здесь, в сообщении группы Google обходной путь

Пост относится к 2015 году, поэтому проблема, кажется, известна в течение некоторого времени.

Код

Поэтому добавьте в код

plt.view.interactive = False

перед вызовом fig.visuals_at и впоследствии do

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)

Test

Test Output

...