我有一个使用matplotlib和QT4Agg后端的Python基本图像查看器程序。功能之一是从2D-FFT生成2D功率谱,并将其放置在一个图中的第二个图中。我想添加一个按钮,该按钮获取FFT图像并将其弹出到另一个窗口中,以便可以对其进行更详细的分析。
我的代码当前正在执行我需要做的所有事情,但同时也会向终端发出QT异常或某种警告(此警告正在OS X下运行:]
“ QCoreApplication :: exec:事件循环已经在运行”
def popout(event):
nfig, nfftax = pylab.subplots(1, 1)
imgtoconv = getArr(files[imgindex])
fftimg = np.abs(fftpack.fftshift(fftpack.fft2(imgtoconv)))**2
nfftax.imshow(np.log10(fftimg), cmap=cm.Greys_r)
pylab.show()
我定义了一个按钮,并通过Button.on_clicked(popout)链接到popout()函数在程序的主循环中,将启动一个图形,并用两个图显示。因此pylab.show()已经被调用过一次
我遇到的问题似乎是我再次调用pylab.show(),这正在生成异常或警告事件循环已启动。
我尝试使用pylab.draw()而不是pylab.show(),但是当我这样做时,单击按钮不会显示新的图形
是否有一种简便的方法来禁止显示此警告?还是有另一种方法产生新图并使其可见而无需调用pylab.show()?
编辑:在创建新图形和新轴之后,我还尝试添加nfig.canvas.draw(),然后在popout()函数末尾调用pylab.draw()。这仍然没有显示新的数字onclick
EDIT2:切换为使用TKAgg后端并重新调用pylab.show()可以使问题消失。关于为什么这只是QT4Agg后端中的一个问题的任何想法?
您是否尝试过使用ion()
?使用按钮回调中的多个图形时,我遇到了相同的问题。对我来说,在popout()
函数内部使用此代码可以解决问题:
import matplotlib.pyplot as p
import numpy as np
p.ion()
p.close(1)
p.close(2)
p.figure(1)
p.plot(np.random.normal(size=100))
p.figure(2)
p.plot(np.random.normal(size=100))
据我所知,这迫使matplotlib使用其自己的线程来处理所有图形,而不会与GUI的主循环冲突。我关闭了数字以完全重置它们并释放了内存,但是p.clf()
也可以工作。
如果您要更新图不使用ion(),请使用此行进行更新
fig.canvas.draw()
示例程序以在鼠标单击位置上绘制红点
import matplotlib.pyplot as plt
def plot_on_graph(ix, iy):
global fig
plt.scatter([ix],[iy], color='red')
fig.canvas.draw()
def onclick(event):
global ix,iy
ix, iy = event.xdata, event.ydata
print(ix, iy)
plot_on_graph(ix, iy)
fig = plt.figure()
cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()