python - 按下“1”按钮后缩放停止工作,但仅在子图中
问题描述
我正在开发一个简单的 GUI 来使用Matplotlib 自己的事件处理来分析一些数据。总的来说,这很有效,但是在过去的几个小时里,我一直在为一些奇怪的错误而摸不着头脑。
下面的代码是我的真实应用程序的一个严重缩减的版本。它的工作方式是您可以单击图像以通过单击鼠标左键和右键单击来添加和删除点。这种“编辑模式”可以通过按“0”和“1”键来打开和关闭。
当图像是唯一的子图时,这可以正常工作。错误是,如果图像是几个子图中的一个,则一旦您打开编辑模式,Matplotlib 的缩放按钮就会停止工作(通过按下“1”按钮,它将 on_click 函数安装为 button_press_event 的处理程序)。此后,按“o”或缩放按钮会更改光标,但不再出现缩放区域的矩形。我猜这个处理程序会以某种方式与 Matplotlib 的内部结构混淆。
有谁明白为什么缩放在单个子图的情况下继续工作,但在安装 on_click 处理程序以防多个子图的情况下停止工作?. 要在工作版本和错误版本之间更改注释/取消注释生成图形和子图的指示行。我正在使用来自 anaconda 的 python 2.7.14 和 matplotlib 2.2.2。
import numpy as np
import matplotlib.pyplot as plt
class Points(object):
def __init__(self, ax):
self.ax = ax
# make dummy plot, points will be added later
self.dots, = ax.plot([], [], '.r')
self.x = []
self.y = []
def onclick(self, event):
print 'point.onclick'
# only handle clicks in the relevant axis
if event.inaxes is not self.ax:
print 'outside axis'
return
# add point with left button
if event.button == 1:
self.x.append(event.xdata)
self.y.append(event.ydata)
# delete point with right button
if event.button == 3 and len(self.x) > 0:
imn = np.argmin((event.xdata - self.x)**2 + (event.ydata - self.y)**2)
del self.x[imn]
del self.y[imn]
self.dots.set_data(self.x, self.y)
plt.draw()
#### THIS WORKS ####
fig, ax3 = plt.subplots()
####################
#### THIS DOES NOT WORK ####
# fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(2, 2)
############################
ax3.imshow(np.random.randn(10, 10))
ax3.set_title('Press 0/1 to disable/enable editing points')
points = Points(ax3)
# initial state
cid_click = None
state = 0
def on_key(event):
global cid_click, state
print 'you pressed %r' % event.key
if event.key in '01':
if cid_click is not None:
print 'disconnect cid_click', cid_click
fig.canvas.mpl_disconnect(cid_click)
cid_click = None
state = int(event.key)
if state:
print 'connect'
cid_click = fig.canvas.mpl_connect('button_press_event', points.onclick)
# plt.draw()
print 'state = %i, cid = %s' % (state, cid_click)
cid_key = fig.canvas.mpl_connect('key_press_event', on_key)
plt.show()
解决方案
这是迄今为止我遇到的最奇怪的错误之一。问题与按键有关1。由于某种未知原因,这似乎会杀死其他事件的回调。我创建了一个关于它的错误报告。
目前,解决方案是不使用1密钥,而是使用a/d键(用于激活/停用)。
# initial state
cid_click = None
state = "d"
def on_key(event):
global cid_click, state
print 'you pressed %r' % event.key
if event.key in 'ad':
if cid_click is not None:
print 'disconnect cid_click', cid_click
fig.canvas.mpl_disconnect(cid_click)
cid_click = None
state = event.key
if state == "a":
print 'connect'
cid_click = fig.canvas.mpl_connect('button_press_event', points.onclick)
print 'state = %s, cid = %s' % (state, cid_click)
推荐阅读
- spring - JoinPoint 以匹配 EntityManager 方法
- internet-explorer - 当设置为拒绝所有加载项时,E11 阻止执行 htc 文件,除非设置了加载项列表策略中的特别允许
- recursion - 为什么这不是尾递归
- authorize.net - 在 authorize.net 中验证信用卡而不指定金额
- r - 在 R 中的一个图上绘制许多(即 1000 多个)分布
- wordpress - 更具体/详细的 WooCommerce 结帐错误?
- wordpress - 在 wordpress 网站中隐藏 Div
- android - 如何从片段中删除项目
- angular - ng-if 只触发一次
- javascript - 如何以编程方式在谷歌浏览器中选择麦克风?