FuncAnimation Plot hangs when length of list increases
Question: 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()
    


Answer: Found the solution, use wx.calllater instead of animating the graph, i.e.
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)
    

