简体   繁体   中英

FuncAnimation Plot hangs when length of list increases

For my college project I am developing a traffic generation script in python. This traffic generation script makes use to multiprocessing module to generate large amount of http traffic in concurrent fashion. My scripts are working fine and now I am trying to build a user friendly GUI using wxpython to operate working of these scripts. I have kept both these scripts separate.In my GUI script, I have imported my traffic generation (work) script and then I call its function(work.time_func() or work.requests_func()) to run multiprocesses when initiated by user on GUI. Upto here my script works fine. Further, in my wxpython panel I have appended a graph that plots some data (shared list between various processes) related to traffic generation script ( work.rt ( multiprocessing.Manager().list())-->which is actually shared data between all processes). now the length of data (len(work.rt)) to be plotted here goes upto 1,00,00,000, but my GUI hangs after plotting around 2500 datas only. What could be the problem here? How to overcome it? I am using centos 6.5. Here is my code:

import work #traffic generation script
import wx.lib.scrolledpanel as scrolled
import matplotlib.animation as anim
import matplotlib.figure as mfigure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
import time
import wx
import os
import paramiko
import sys
from paramiko import SSHConfig
from paramiko import SSHClient
from multiprocessing import Value
import thread
class TabPanel1(scrolled.ScrolledPanel):
    def __init__(self,parent):
        scrolled.ScrolledPanel.__init__(self,parent=parent)
        self.SetDoubleBuffered(True)
        self.label_0=wx.StaticText(self,-1,"Mode of Operation:",(40,25))
        self.label_0_list=['Request Based','Time Based']
        self.label_0_combo=wx.ComboBox(self,-1,'None',(200,25),wx.DefaultSize,self.label_0_list,wx.CB_DROPDOWN)
        self.label_1=wx.StaticText(self,-1,"Number of Clients:",(40,75))
        self.label_1_list=['1','2','3','4','5','10','15','20','25','30','35','40','45','50']
        self.label_1_combo=wx.ComboBox(self,-1,'None',(200,75),wx.DefaultSize,self.label_1_list,wx.CB_DROPDOWN)
        self.label_2=wx.StaticText(self,-1,"Actions:",(40,125))
        self.label_2_list=['Web','Download','Video']
        self.label_2_combo=wx.ComboBox(self,-1,'None',(200,125),wx.DefaultSize,self.label_2_list,wx.CB_DROPDOWN)
        self.label_3=wx.StaticText(self,-1,"Number of Servers:",(40,175))
        self.label_3_list=['1','2','3','4','5','6','7','8','9','10']
        self.label_3_combo=wx.ComboBox(self,-1,'None',(200,175),wx.DefaultSize,self.label_3_list,wx.CB_DROPDOWN)
        self.label_4=wx.StaticText(self,-1,"Size of File:",(40,225))
        self.label_4_list=['small-files','0to1kb','10kb','20kb','50kb','70kb','100kb','200kb','500kb','700kb','1mb','2mb','video1.2mb','video2.2mb','video2mb','video3mb','allfiles']
        self.label_4_combo=wx.ComboBox(self,-1,'None',(200,225),wx.DefaultSize,self.label_4_list,wx.CB_DROPDOWN)
        self.label_5=wx.StaticText(self,-1,"RampUpTime(ms):",(40,275))
        self.label_5_list=['500','750','1000','2000','5000']
        self.label_5_combo=wx.ComboBox(self,-1,'None',(200,275),wx.DefaultSize,self.label_5_list,wx.CB_DROPDOWN)
        self.label_6_list=['1minute','5minutes','10minutes','15minutes','30minutes','1hour','2hours','3hours','4hours','5hours','6hours','10hours','12hours','15hours','18hours','24hours','Mode is Request Based']
        self.label_6=wx.StaticText(self,-1,"Test Time:",(40,325))
        self.label_6_combo=wx.ComboBox(self,-1,'None',(200,325),wx.DefaultSize,self.label_6_list,wx.CB_DROPDOWN)
        self.label_7_list=['10000','20000','40000','50000','70000','100000','200000','500000','700000','1000000','Mode is Time Based']
        self.label_7=wx.StaticText(self,-1,"Number of Requests:",(40,375))
        self.label_7_combo=wx.ComboBox(self,-1,'None',(200,375),wx.DefaultSize,self.label_7_list,wx.CB_DROPDOWN)
        self.failed=wx.StaticText(self,-1,"Failed Requests:",(400,25))
        self.result=wx.StaticText(self, label="",pos=(525,25))  
        self.result.SetForegroundColour(wx.RED)
        self.scripttime=wx.StaticText(self,-1,"Script_Run_Time:",(400,50))
        self.tresult=wx.StaticText(self, label="",pos=(525,75)) 
        self.tresult.SetForegroundColour(wx.RED)    
        self.ok=wx.Button(self,label="OK",pos=(40,425))
        self.ok.Bind(wx.EVT_BUTTON,self.onok)
        self.cancle=wx.Button(self,label='Cancle',pos=(140,425))
        self.cancle.Bind(wx.EVT_BUTTON,self.oncancle)
        self.run=wx.Button(self,label="RUN",pos=(240,425))
        self.run.Bind(wx.EVT_BUTTON,self.onrun)
        self.cap=wx.Button(self,label="Capture",pos=(340,425))
        self.cap.Bind(wx.EVT_BUTTON,self.oncap)
        self.testcomplete=wx.Button(self,label="Test Complete",pos=(440,425))
        self.testcomplete.Bind(wx.EVT_BUTTON,self.oncomplete)
        self.action=self.label_2_combo.GetValue()
        self.xmax=len(work.rt) if len(work.rt)>100 else 100
        self.xmin=self.xmax-100
        self.myfig=mfigure.Figure(dpi=50)
        self.axes=self.myfig.add_subplot(111)
        self.axes.set_xbound(lower=self.xmin,upper=self.xmax)
        self.canvas=FigureCanvas(self,-1,self.myfig)
        self.canvas.SetPosition((400,100))  
        self.toolbar=NavigationToolbar(self.canvas)
        self.toolbar.Realize()
        self.toolbar.SetPosition((400,75))
        tw,th=self.toolbar.GetSizeTuple()
        fw,fh=self.canvas.GetSizeTuple()
        self.toolbar.SetSize(wx.Size(fw,th))
        self.toolbar.update()
        self.animator=anim.FuncAnimation(self.myfig,self.animator,interval=1000,repeat=True)
        self.SetupScrolling()
    def onok(self,event):
        self.mode=self.label_0_combo.GetValue()
        self.noc=int(self.label_1_combo.GetValue())
        work.noc=self.noc
        self.action=self.label_2_combo.GetValue()
        if (self.action=='Web'):
            work.action=Value('i',0)
        elif(self.action=='Download'):
            work.action=Value('i',1)
        elif(self.action=='Video'):
            work.action=Value('i',2)
        else:
            self.label_2=wx.StaticText(self,-1,"Please restart & select proper Action",(40,475))
            self.Close()
        self.nos=int(self.label_3_combo.GetValue())
        work.nos=Value('i',self.nos)        
        self.filesize=self.label_4_combo.GetValue()
        if (self.filesize=='small-files'):
            work.low=Value('i',0)
            work.high=Value('i',1)
        elif (self.filesize=='0to1kb'):
            work.low=Value('i',1)
            work.high=Value('i',2)
        elif (self.filesize=='10kb'):
            work.low=Value('i',2)
            work.high=Value('i',3)
        elif (self.filesize=='20kb'):
            work.low=Value('i',3)
            work.high=Value('i',4)
        elif (self.filesize=='50kb'):
            work.low=Value('i',4)
            work.high=Value('i',5)
        elif (self.filesize=='70kb'):
            work.low=Value('i',5)
            work.high=Value('i',6)
        elif (self.filesize=='100kb'):
            work.low=Value('i',6)
            work.high=Value('i',7)
        elif (self.filesize=='200kb'):
            work.low=Value('i',7)
            work.high=Value('i',8)
        elif (self.filesize=='500kb'):
            work.low=Value('i',8)
            work.high=Value('i',9)
        elif (self.filesize=='700kb'):
            work.low=Value('i',9)
            work.high=Value('i',10)
        elif (self.filesize=='1mb'):
            work.low=Value('i',10)
            work.high=Value('i',11)
        elif (self.filesize=='2mb'):
            work.low=Value('i',11)
            work.high=Value('i',12)
        elif (self.filesize=='video1.2mb'):
            work.low=Value('i',12)
            work.high=Value('i',13)
        elif (self.filesize=='video2.2mb'):
            work.low=Value('i',13)
            work.high=Value('i',14)
        elif (self.filesize=='video2mb'):
            work.low=Value('i',14)
            work.high=Value('i',15)
        elif (self.filesize=='video3mb'):
            work.low=Value('i',15)
            work.high=Value('i',16)
        elif (self.filesize=='allfiles'):
            work.low=Value('i',0)
            work.high=Value('i',16)
        else:
            self.label_2=wx.StaticText(self,-1,"Please restart & select proper file size",(40,475))
            self.Close()
        self.rampuptime=int(self.label_5_combo.GetValue())
        work.rampuptime=(self.rampuptime/1000)
        self.mytime=self.label_6_combo.GetValue()
        if (self.mytime=='1minute'):
            self.testtime=60.0
        elif (self.mytime=='5minutes'):
            self.testtime=300.0
        elif (self.mytime=='10minutes'):
            self.testtime=600.0
        elif (self.mytime=='15minutes'):
            self.testtime=900.0
        elif (self.mytime=='30minutes'):
            self.testtime=1800.0
        elif (self.mytime=='1hour'):
            self.testtime=3600.0
        elif (self.mytime=='2hours'):
            self.testtime=7200.0
        elif (self.mytime=='3hours'):
            self.testtime=10800.0
        elif (self.mytime=='4hours'):
            self.testtime=14400.0
        elif (self.mytime=='5hours'):
            self.testtime=18000.0
        elif (self.mytime=='6hours'):
            self.testtime=21600.0
        elif (self.mytime=='10hours'):
            self.testtime=36000.0
        elif (self.mytime=='12hours'):
            self.testtime=43200.0
        elif (self.mytime=='15hours'):
            self.testtime=54000.0
        elif (self.mytime=='18hours'):
            self.testtime=64800.0
        elif (self.mytime=='24hours'):
            self.testtime=86400.0
        elif (self.mytime=='Mode is Request Based'):
            work.end_time=0
        else:
            self.label_2=wx.StaticText(self,-1,"Please restart & select proper test time",(40,475))
            self.Close()
        self.nor=self.label_7_combo.GetValue()
    def oncancle(self,event):
        sys.exit()
    def oncap(self,event):
        os.system("gnome-terminal -e 'tcpdump -ni eth0 port 80 -w cap.pcap'")
    def onrun(self,event):
        time.sleep(1)
        self.scriptstart=float(time.time())
        self.mode=self.label_0_combo.GetValue()
        if (self.mode=='Time Based'):
            work.end_time=time.time()+self.testtime
            thread.start_new_thread(work.time_func, ())
        elif(self.mode=='Request Based'):
            work.number_of_requests=int(self.nor)
            thread.start_new_thread(work.requests_func, ())
    def oncomplete(self,event):
        self.label_2=wx.StaticText(self,-1,"All work Done..!! To generate traffic again, Please restart the script ",(40,475))  
        x=len(work.rt)
        y=work.scriptend-self.scriptstart
        self.result.SetLabel("Errors=%d/%d"%(work.error_count.value,x))
        self.tresult.SetLabel("%f"%y)
    def animator(self,i):
        self.axes.cla()
        self.axes.set_ylabel("Response Time")
        self.axes.set_xlabel("Number of Files")
        return self.axes.plot(work.rt)
class DemoFrame(wx.Frame):
    def __init__ (self):
        wx.Frame.__init__(self,None,wx.ID_ANY,"Python_Scripts",size=(800,500))
        self.mypanel=TabPanel1(self)
        self.SetDoubleBuffered(True)
        self.Layout()
        self.Centre()
        self.Show()
    def onexit(self,event):
        sys.exit()
if __name__=='__main__':
    app=wx.App(False)
    frame=DemoFrame()
    frame.Show()
    app.MainLoop()

Found the solution, use wx.calllater instead of animating the graph, ie instead of using funcanimation with 1000 millisecond of interval time,first call the plotting function that simple draws the canvas and then within that function provide wx.calllater at end that calls itself after every 1000 miliseconds eg.

main_function():
    plot_function()
plot_function(self):
    <plotting of graph>
    wx.CallLater(1000,self.plot_function)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM