为什么pyplot窗口从独立函数生成而不是从事件处理程序调用的函数生成时表现不同?

时间:2015-08-13 18:40:54

标签: matplotlib pyqt4 qtgui

当我自己运行setup_plotdataq函数时,pyplot窗口的行为与预期一致,即在运行完成后,导航工具栏中的按钮(平移/缩放等)处于活动状态。但是,当我导入函数并从主程序中的按钮事件处理程序调用它们时,pyplot窗口在运行完成后保持活动状态:它仍然接受数据并且工具栏按钮处于非活动状态。如何在不关闭绘图窗口的情况下停止绘图?这是一个片段:

class MyWindowClass(QtGui.QWidget, form_class):
    def __init__(self, parent=None):
       QtGui.QWidget.__init__(self, parent)
       self.setupUi(self)
       self.pushButton_Run.clicked.connect(self.pushbutton_run_clicked)
       self.pushButton_Stop.clicked.connect(self.pushbutton_stop_clicked)

    def pushbutton_run_clicked(self):
        # get line edit values here 
        functions.setup_plot()
        functions.dataq(steptime, runtime, CO2_1, CO2_2)

1 个答案:

答案 0 :(得分:1)

我尝试通过根据您提供给我们的代码段创建一个简单的MCVE来重现您的问题。我唯一能找到的就是让我的简单应用程序按你所描述的那样运行,如果我没有将matplotlib的backend设置为Qt4Agg

from PyQt4 import QtGui
import sys
import numpy as np

import matplotlib as mpl
mpl.use('Qt4Agg')
import matplotlib.pyplot as plt

class MyWindowClass(QtGui.QWidget):
    def __init__(self, parent=None):
       super(MyWindowClass, self).__init__(parent)

       pushButton_Run = QtGui.QPushButton('Run')
       pushButton_Run.clicked.connect(self.pushbutton_run_clicked)

       layout = QtGui.QGridLayout()
       layout.addWidget(pushButton_Run, 0, 0)
       self.setLayout(layout)

    def pushbutton_run_clicked(self):

        fig, ax = setup_plot()                        
        dataq(fig, ax)

def setup_plot():

    fig, ax = plt.subplots()
    fig.canvas.manager.show()

    return fig, ax

def dataq(fig, ax):
    for i in range(200):
        ax.plot(np.random.rand(1), np.random.rand(1), 'o')
        fig.canvas.draw()
        fig.canvas.flush_events()

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)    
    mywindow = MyWindowClass()
    mywindow.show()      
    sys.exit(app.exec_())

enter image description here

更新 - 第二个例子:

这是设置您的艺术家的另一种方式,可以让您在多个功能中更轻松地使用它们,并且可以使他们的操作更方便。

from PyQt4 import QtGui
import sys
import numpy as np

import matplotlib as mpl
mpl.use('Qt4Agg')
import matplotlib.pyplot as plt

class MyWindowClass(QtGui.QWidget):
    def __init__(self, parent=None):
       super(MyWindowClass, self).__init__(parent)

       #---- generate some data ----

       self.x = np.random.rand(50)
       self.y = np.random.rand(50)

       #---- create a layout ----

       pushButton_Run = QtGui.QPushButton('Run')
       pushButton_Run.clicked.connect(self.pushbutton_run_clicked)

       pushButton_Clear = QtGui.QPushButton('Clear')
       pushButton_Clear.clicked.connect(self.clear_plot)

       layout = QtGui.QGridLayout()
       layout.addWidget(pushButton_Run, 0, 0)
       layout.addWidget(pushButton_Clear, 1, 0)
       self.setLayout(layout)

       #---- init artists ----

       self.fig, self.ax = plt.subplots()
       self.fig.canvas.manager.show()

    def clear_plot(self):
        self.ax.cla()
        self.fig.canvas.draw()
        self.fig.canvas.flush_events()

    def pushbutton_run_clicked(self):
        self.setEnabled(False)
        self.ax.cla()   
        dataq(self.fig, self.ax, self.x, self.y)
        dataq2(self.fig, self.ax, self.x, self.y)
        self.setEnabled(True)

def dataq(fig, ax, x, y):            
    for i in range(len(x)):
        ax.plot(x[i], y[i], 'o')
        fig.canvas.draw()
        fig.canvas.flush_events()

def dataq2(fig, ax, x, y):
    for i in range(len(x)-1):
        ax.plot(x[i:i+2], y[i:i+2], '-')
        fig.canvas.draw()
        fig.canvas.flush_events()

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)    
    mywindow = MyWindowClass()
    mywindow.show()      
    sys.exit(app.exec_())