让 SpanSelector 等待特定的按键事件
Making SpanSelector wait for a specific keypress event
我有一个脚本可以生成带有 SpanSelector 小部件的数据图。该小部件调用 select_window(vmin, vmax)
闭包函数,该函数使用 window 限制来分析所选数据。分析函数生成另一个具有一些视觉结果的图。
SpanSelector 的默认行为是在选择后立即执行 select_window
。由于计算有点繁重,我希望用户通过按键确认选择的 window 。第一个选项是使用 plt.waitforbuttonpress
,但这会响应所有按键事件,包括 pan/zoom/etc 默认使用的按键事件。在 matplotlib 中。
第二个选项是直接连接 key_press_event
,但我不确定在何处连接和断开事件处理程序。
工作示例,使用 waitforbuttonpress:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector
def analyse(data, window_min, window_max):
sliced_data = data[window_min:window_max]
print(sliced_data)
fig, ax = plt.subplots()
ax.plot(sliced_data)
plt.pause(0.001)
def plot_data(data):
fig, ax = plt.subplots()
ax.plot(data)
def select_window(vmin, vmax):
if plt.waitforbuttonpress(60):
window_min = int(np.floor(vmin))
window_max = int(np.ceil(vmax))
analyse(data, window_min, window_max)
widget = SpanSelector(
ax, select_window, 'horizontal', useblit=True, span_stays=True,
minspan=1
)
plt.show()
return widget # Keeping a reference so it isn't garbage collected.
if __name__ == '__main__':
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
widget = plot_data(data)
关键是在正确的地方使用 fig.canvas.mpl_connect
和 fig.canvas.mpl_disconnect
。需要断开连接,否则绘图将在连续 window 个选择中累积。
这是解决方案,它只接受回车键作为有效的 window 确认。可以通过 event.key
.
访问其他密钥
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector
def analyse(data, window_min, window_max):
sliced_data = data[window_min:window_max]
print(sliced_data)
fig, ax = plt.subplots()
ax.plot(sliced_data)
plt.pause(0.001)
def plot_data(data):
fig, ax = plt.subplots()
ax.plot(data)
def select_window(vmin, vmax):
def _confirm_selection(event):
if event.key == 'enter': # Make the selector wait for <enter> key
window_min = int(np.floor(vmin))
window_max = int(np.ceil(vmax))
analyse(data, window_min, window_max)
fig.canvas.mpl_disconnect(cid) # Disconnect the event after analysis
cid = fig.canvas.mpl_connect('key_press_event', _confirm_selection)
widget = SpanSelector(
ax, select_window, 'horizontal', useblit=True, span_stays=True,
minspan=1
)
plt.show()
return widget # Keeping a reference so it isn't garbage collected.
if __name__ == '__main__':
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
widget = plot_data(data)
闭包 mpl_disconnect
可以访问事件 ID。因此,事件可以在它自己的回调中断开连接(即_confirm_selection
)。我不确定这是否是最好的方法,欢迎改进,但它确实有效 ;)
我有一个脚本可以生成带有 SpanSelector 小部件的数据图。该小部件调用 select_window(vmin, vmax)
闭包函数,该函数使用 window 限制来分析所选数据。分析函数生成另一个具有一些视觉结果的图。
SpanSelector 的默认行为是在选择后立即执行 select_window
。由于计算有点繁重,我希望用户通过按键确认选择的 window 。第一个选项是使用 plt.waitforbuttonpress
,但这会响应所有按键事件,包括 pan/zoom/etc 默认使用的按键事件。在 matplotlib 中。
第二个选项是直接连接 key_press_event
,但我不确定在何处连接和断开事件处理程序。
工作示例,使用 waitforbuttonpress:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector
def analyse(data, window_min, window_max):
sliced_data = data[window_min:window_max]
print(sliced_data)
fig, ax = plt.subplots()
ax.plot(sliced_data)
plt.pause(0.001)
def plot_data(data):
fig, ax = plt.subplots()
ax.plot(data)
def select_window(vmin, vmax):
if plt.waitforbuttonpress(60):
window_min = int(np.floor(vmin))
window_max = int(np.ceil(vmax))
analyse(data, window_min, window_max)
widget = SpanSelector(
ax, select_window, 'horizontal', useblit=True, span_stays=True,
minspan=1
)
plt.show()
return widget # Keeping a reference so it isn't garbage collected.
if __name__ == '__main__':
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
widget = plot_data(data)
关键是在正确的地方使用 fig.canvas.mpl_connect
和 fig.canvas.mpl_disconnect
。需要断开连接,否则绘图将在连续 window 个选择中累积。
这是解决方案,它只接受回车键作为有效的 window 确认。可以通过 event.key
.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector
def analyse(data, window_min, window_max):
sliced_data = data[window_min:window_max]
print(sliced_data)
fig, ax = plt.subplots()
ax.plot(sliced_data)
plt.pause(0.001)
def plot_data(data):
fig, ax = plt.subplots()
ax.plot(data)
def select_window(vmin, vmax):
def _confirm_selection(event):
if event.key == 'enter': # Make the selector wait for <enter> key
window_min = int(np.floor(vmin))
window_max = int(np.ceil(vmax))
analyse(data, window_min, window_max)
fig.canvas.mpl_disconnect(cid) # Disconnect the event after analysis
cid = fig.canvas.mpl_connect('key_press_event', _confirm_selection)
widget = SpanSelector(
ax, select_window, 'horizontal', useblit=True, span_stays=True,
minspan=1
)
plt.show()
return widget # Keeping a reference so it isn't garbage collected.
if __name__ == '__main__':
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
widget = plot_data(data)
闭包 mpl_disconnect
可以访问事件 ID。因此,事件可以在它自己的回调中断开连接(即_confirm_selection
)。我不确定这是否是最好的方法,欢迎改进,但它确实有效 ;)