使用pyQtGraph生成Two Axix图时RAM内存增加

时间:2013-11-26 08:40:21

标签: python-2.7 plot pyqtgraph

我正在尝试绘制服务器收到的实时数据,同时我的CPU(Windows XP操作系统)的RAM记忆增加,我从链接“{{获取了Luke-campagnola的最新更新。 3}}“

任何帮助或建议都需要提前感谢。

我在这里附上整个代码......

import sys
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import collections
import random
import time
import math
import numpy as np
from pyqtgraph.ptime import time


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

        sampleinterval=0.1
        self.myvar = 0
        self.prevdt=0
        self.dt1 = 0


        app = QtGui.QApplication([])

        self.plot_param1 = []
        self.plot_param2 = []
        self.plot_param3 = []
        self.plot_param4 = []
        for g in range(0,100):
            self.plot_param1.append(g/100)
            self.plot_param2 .append((g+1)/100)
            self.plot_param3.append(g/100)
            self.plot_param4.append((g+1)/100)

        self.samplesize = 100;
        self.samples     = range(0,self.samplesize)

        for i in range(len(self.samples)):
            self.samples[i] = self.samples[i]/100.0

        self.framecount = 0;

        pg.mkQApp()
        self.pw = pg.PlotWidget()

        self.pw.show()
        self.p1 = self.pw.plotItem
        self.p2 = pg.ViewBox()
        self.p1.showAxis('right')
        self.p1.scene().addItem(self.p2)
        self.p2.setGeometry(self.p1.vb.sceneBoundingRect())
        self.p1.getAxis('right').linkToView(self.p2)
        self.p2.setXLink(self.p1)

        self.pw.setLabel('bottom', 'Time in Secs')
        self.pw.setLabel('left', 'Velocity in rpm')
        self.pw.setLabel('right', 'load in Nm')

    def update(self):

        self.p1.plot(self.samples, self.plot_param3)

        self.p2.addItem(self.p1.plot(self.samples, self.plot_param4, pen='b'))  


        self.dt1  = self.dt1+1

        self.p1.setYRange(min(self.plot_param3), max(self.plot_param3))
        self.p2.setXRange(self.dt1-1,self.dt1)
        self.p2.setYRange(min(self.plot_param4), max(self.plot_param4))

        if self.framecount == 0:    
            flushloop = self.samplesize 
        else:   
            flushloop = self.samplesize+1   

        for flush in range(1,flushloop):    

            self.samples.pop(0) 


    # below code is to prepare for next sample  
    self.framecount = self.framecount + 1   
    k=0
    for update in range(self.framecount*self.samplesize,
        self.framecount*self.samplesize+self.samplesize):
        if(0):
            self.plot_param1.append(self.framecount+(update/2))
            self.plot_param2.append(self.framecount+ (update/2))
            self.myvar=self.myvar-1
        else:
            self.myvar=self.myvar+1
            #self.plot_param2.append(self.framecount+ (update/2))
            #self.plot_param1.append(self.framecount+(update/2))


        self.samples.append(update/100.0)

if(self.dt1<100):
    self.plot_param1 =  np.cos(np.linspace(0, 2*np.pi, 101))
    self.plot_param3 = self.plot_param1.tolist()
    self.plot_param2 =  np.sin(np.linspace(0, 4*np.pi, 101))
    self.plot_param4 = self.plot_param2.tolist()

if((self.dt1>=100)and (self.dt1 < 200)):
    self.plot_param1 =  np.cos(np.linspace(0, 20*np.pi, 101))
    self.plot_param3 = self.plot_param1.tolist()
    self.plot_param2 =  np.sin(np.linspace(0, 40*np.pi, 101))
    self.plot_param4 = self.plot_param2.tolist()

if((self.dt1>=200)and (self.dt1 < 300)):
    for f in range(0,100):

        self.plot_param1 =  np.cos(np.linspace(0, 20*np.pi, 101))
    self.plot_param3 = self.plot_param1.tolist()
    #self.plot_param3.append(1+f)
    self.plot_param2 =  np.cos(np.linspace(0, 20*np.pi, 101))
    #self.plot_param4.append(3+f)
    self.plot_param4 = self.plot_param2.tolist()




if(self.dt1 >= 300):
    self.plot_param1 =  np.cos(np.linspace(0, 10*np.pi, 101))
    self.plot_param3 = self.plot_param1.tolist()
    self.plot_param2 =  np.sin(np.linspace(0, 80*np.pi, 101))
    self.plot_param4 = self.plot_param2.tolist()



    for i in range (len(self.plot_param3)):

        self.plot_param3[i] = 20 * self.plot_param3[i]



if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)    
    myapp = DynamicPlotter()
    for i in range(0,100):
        myapp.update()


    timer = QtCore.QTimer()         
    timer.timeout.connect(myapp.update) 
    timer.start(50)

2 个答案:

答案 0 :(得分:1)

您发布的代码存在一些问题:

  1. update()每次调用时都会向场景添加新的绘图曲线,这可能是您使用内存的原因。它也会影响性能。要解决此问题,您可以在self.p1.clear()

  2. 的开头致电update()
  3. 代码尝试创建QApplication实例至少三次,这可能导致崩溃或挂起:

    • DynamicPlotter.__init__有一行app = QtGui.QApplication([])
    • DynamicPlotter.__init__有另一行pg.mkQApp(),它使用相同的
    • 底部的__main__块也会调用QtGui.QApplication([])

    另请注意,对于DynamicPlotter的每个实例,将调用一次QApplication()。函数pg.mkQApp()可以安全地多次调用,因为它将检查是否已经创建了QApplication。

  4. DynamicPlotter是QWidget的子类,但既不显示也不用作窗口小部件。这是一个小问题,但可能会在以后造成混淆。

答案 1 :(得分:1)

我根据你的评论更新了代码,我能够解决内存问题。

当我去调试内存问题时,我也发现了

1) File PlotItem.py function addItem() has
   self.items.append(item)
   self.dataItems.append(item)
   self.curves.append(item)

2) File ViewBox.py function addItem() has
   self.addedItems.append(item)

上面提到的4个列表项不断累积,它们不会释放先前存储的实例。

不太确定为什么需要累积,我使用下面列出的命令删除了数组。

del self.items [0:len(self.items)]
del self.dataItems [0:len(self.dataItems)]
del self.curves [0:len(self.curves)]
del self.addedItems [0:len(self.addedItems)]

通过添加以上4行命令我没有发现任何问题。能否请您提供相关信息。

此致 Pradeep K.