Как ограничить `mpl_connect` для` axes` вместо целой `figure`? - PullRequest
0 голосов
/ 15 мая 2019

Я пишу программу, в которой пользователь может интерактивно изменять сюжет.Я использую 3 mpl_connect функции (key_press_event button_press_event button_release_event) плюс 4 текстовых поля (mwidgets.TextBox).

Каждый раз, когда я набираю текст в текстовые поля, процесс идет медленно иЯ думаю, это потому, что когда я щелкаю и пишу текстовое поле, оно без необходимости запускает 3 "соединения mpl" (key_press_event button_press_event button_release_event).

3текстовые поля находятся за пределами «объекта осей», и поэтому мне интересно, есть ли способ ограничить «связи mpl» только с осью интереса.То есть вместо того, чтобы кодировать следующее:

cid1 = figure.canvas.mpl_connect('key_press_event', onPressKey)
cid2 = figure.canvas.mpl_connect('button_press_event', onPressButton)
cid3 = figure.canvas.mpl_connect('button_release_event', onReleaseButton)

для кодирования чего-то вроде (обратите внимание на подстановку canvas для axes):

cid1 = figure.axes.mpl_connect('key_press_event', onPressKey)
cid2 = figure.axes.mpl_connect('button_press_event', onPressButton)
cid3 = figure.axes.mpl_connect('button_release_event', onReleaseButton)

Есть ли обходной путь?

Любой комментарий приветствуется!

1 Ответ

1 голос
/ 16 мая 2019

Посмотрите на этот упрощенный пример и посмотрите, что возвращают операторы print:

import numpy as np
import matplotlib as mpl

import matplotlib.pyplot as plt
from matplotlib.widgets import TextBox

fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
t = np.arange(-2.0, 2.0, 0.001)
s = t ** 2
initial_text = "t ** 2"
l, = plt.plot(t, s, lw=2)

def submit(text):
    ydata = eval(text)
    l.set_ydata(ydata)
    ax.set_ylim(np.min(ydata), np.max(ydata))
    plt.draw()

def onPressKey(event):
    print('you pressed key {0} in ax {1}'.format( event.key, event.inaxes ))
    if event.inaxes in [ax]:
        print("in ax")
    elif event.inaxes in [fig.axes[1]]:
        print("in cid1")
    else:
        print("outside")


axbox = plt.axes([0.1, 0.05, 0.8, 0.075])
text_box = TextBox(axbox, 'Evaluate', initial=initial_text)
text_box.on_submit(submit)

fig.canvas.mpl_connect('key_press_event', onPressKey)

plt.show()

Если вы наведите указатель мыши на «область графика» (т. Е. ax или fig.axes[0]), при каждом нажатии клавиши будут использоваться комбинации клавиш по умолчанию (т. Е. s вызывает диалоговое окно сохранения).

Обработчик onPressKey(event) уже можно использовать для определения того, что делать с этим вводом, так как он знает о event.inaxes, т. Е. Где находилась ваша мышь во время key_press_event. Однако обратите внимание, что как только вы щелкнете внутри виджета TextBox, он будет захватывать ваш ввод (т. Е. Туда записывается s , диалог сохранения не запускается). Если вы теперь переместите указатель мыши за пределы поля texbox , обработчик onPressKey(event) все равно сообщит вам, что ваша мышь находилась в пределах ax во время ввода текста (или, возможно, «снаружи»). ), но это не меняет факта, что виджет TextBox по-прежнему фиксирует ваш ввод, пока вы не нажмите введите .

Краткий ответ: вы не хотите подключать key_press_event к определенной оси, а хотите, чтобы обработчик onPressKey(event), ну обработал его . Каждое нажатие клавиши должно регистрироваться как one key_press_event , так что это, вероятно, не будет виновником в вашем случае (хорошо, если ваш реальный код, например, не настроен для выполнения некоторых дорогостоящих вычислений, например, клавиши e вниз, и у вас есть забытый первый щелчок внутри TextBox.)

...