Skip to main content
 首页 » 编程设计

python之如何强制 matplotlib 更新绘图

2025年05月04日9soundcode

我正在尝试构建一个小图形用户界面,该图形用户界面的绘图会在每次读取新数据样本时更新。我不想用计时器运行它,因为数据将以不同的时间间隔到达。相反,我正在尝试使用信号进行实现,其中数据收集函数将在读取数据时发出信号,然后绘画函数将在绘画完成时发出信号。

现在出现的问题是 Canvas 没有在我调用 canvas.draw() 后立即更新。当这个程序运行时,data_collect() 和 paint() 交替发送信号,但是直到我停止该进程后图形才更新。每当调用 paint() 时,如何强制 matplotlib 更新图形?

下面是一段相对简单的示例代码,它不是最佳的,但希望能传达我正在尝试做的事情的风格......

N_length = 150; 
count = [0]; 
 
def sinval(delay): 
 
    k = 0; 
    x = []; 
 
    # set up data vector with sinusoidal data in it. 
    while k < N_length:   
        x.append(math.sin(2*math.pi*k/N_length)); 
        k += 1; 
 
    def next(): 
 
        time.sleep(delay); 
        outstring = "%0.3e" % (x[count[0]]); 
 
        if (count[0] == (N_length-1)): 
            count[0] = 0; 
        else: 
            count[0] += 1; 
 
        return outstring; 
 
    return next; 
 
 
class DesignerMainWindow(QtGui.QMainWindow, Ui_mplMainWindow): 
 
    def __init__(self, parent = None): 
        super(DesignerMainWindow, self).__init__(parent) 
        self.setupUi(self) 
 
        QtCore.QObject.connect(self.mplStartButton, QtCore.SIGNAL("clicked()"), self.start_graph); 
        QtCore.QObject.connect(self.mplStopButton, QtCore.SIGNAL("clicked()"), self.stop_graph); 
        QtCore.QObject.connect(self.mplQuitButton, QtCore.SIGNAL("clicked()"), QtGui.qApp, QtCore.SLOT("quit()")); 
        QtCore.QObject.connect(self, QtCore.SIGNAL("data_collect()"), self.data_collect); 
        QtCore.QObject.connect(self, QtCore.SIGNAL("paint()"), self.paint); 
 
    def start_graph(self): 
 
        # generates first "empty" plots 
        self.user = []; 
        self.l_user, = self.mpl.canvas.ax.plot([], self.user, label='sine wave'); 
 
        # set up the axes.  
        self.mpl.canvas.ax.set_xlim(0, 300); 
        self.mpl.canvas.ax.set_ylim(-1.1, 1.1); 
        self.mpl.canvas.draw(); 
 
        # start the data collection process. 
        self.delay = 0.05; 
        self.next = sinval(self.delay); 
        self.emit(QtCore.SIGNAL('data_collect()')); 
 
 
    def data_collect(self): 
        outstring = self.next(); 
        self.user.append(float(outstring.split()[0])); 
        self.l_user.set_data(range(len(self.user)), self.user); 
        self.emit(QtCore.SIGNAL('paint()')); 
 
 
    def paint(self): 
        self.mpl.canvas.draw(); 
        self.emit(QtCore.SIGNAL('data_collect()')); 

请您参考如下方法:

我猜想在 paint() 之后调用 QCoreApplication::processEvents 会有所帮助。更优雅的方法是有一个单独的 QThread 用于读取。看看这个thread .