Skip to main content
 首页 » 编程设计

python之几分钟后 numpy plot 创建图形失败 idel

2025年05月04日7jpfss

我使用 web.py 编写了一个小程序,并在其中一个类中使用了 numpy/plot。

我发现每次我第一次访问该页面时,它都运行良好。但是几分钟后, plt.figure() 的功能卡住了!这个函数永远不会返回!这太奇怪了。

请看我的代码:

def DrawMapMain(MapParameter,inputfile='out.txt',imgfile='out.png'): 
    print "DrawMapMain..." 
    plt.ioff() # turn off interactive mode 
    plt.close('all') 
    xmin,xmax,ymin,ymax = MapParameter['xmin'],MapParameter['xmax'],MapParameter['ymin'],MapParameter['ymax'] 
    print('LevelFile:',MapParameter['LevelFile']) 
    LonCenter = (xmin+xmax)/2.0 
    LatCenter = (ymin+ymax)/2.0 
    nx, ny = 200,200 
    if(not os.path.isfile(inputfile)): 
        print(u'输入文件%s不存在,请检查!'%(inputfile)) 
        sys.exit(0) 
    Region = np.loadtxt(inputfile) 
    #print(Region) 
    x,y,z = Region[:,1],Region[:,2],Region[:,3] 
    lon_array = np.linspace(xmin, xmax, nx) 
    lat_array = np.linspace(ymin, ymax, ny) 
 
    print('Data lon/lat box :',x.min(),x.max(),y.min(),y.max()) 
    print(u'离散点插值到网格') 
    zi,xi,yi = Interpolater.griddata_all(x,y,z,lon_array,lat_array,func='line_rbf')#scipy_idw')# #line_rbf 
    print(u'扩展矩阵插值: ') 
    zi,xi,yi,lon_array,lat_array,nx,ny=Interpolater.extened_grid(zi,lon_array,lat_array,zoom=int(2)) # 
    print(u'mask非绘图区域') 
    grid1 = Interpolater.build_inside_mask_array(MapParameter['ShapeFile'],lon_array,lat_array) 
    zi[np.logical_not(grid1)]=np.NaN 
 
    #----------------------------------------------------------------------------------- 
    print(u'Create figure...') 
    #fig = plt.figure(num=1,figsize=(12, 9), dpi=100) 
    fig = plt.figure(figsize=(12, 9), dpi=100) 
    #fig = plt.figure() 
    print(u'Create figure...Done') 
    .........skipped 

我第一次访问该页面时,我得到:

mask非绘图区域 
Create figure... 
Create figure...Done 
(104, 35, 108, 39.5) 

这样还可以,但是过了一段时间,再次访问,我得到了:

mask非绘图区域 
Create figure... 

我可以看到进程“python”占用了我 25% 的 cpu(有 4 个核心),这意味着它陷入了死循环!

这是我的 web.py 类,供引用:

class Month: 
    def POST(self):  
        form = ParameterForm()  
        if not form.validates():  
            return render.Month(form) 
        else: 
            StationInfoFile='./StationsId.txt' # make sure this file is exist. 
            if(not os.path.isfile(StationInfoFile)): 
                print(u'StationInfoFile 文件%s不存在!'%(inputfile)) 
                sys.exit(0) 
            StationsInfo = np.loadtxt(StationInfoFile) # load all data as integer and float, not string 
            StationsId,StationsLon,StationsLat = StationsInfo[:,0].astype(np.int64),StationsInfo[:,1],StationsInfo[:,2] 
            basedir, DataCats, DataCatsDict=u'D:/测试数据',[ u'逐日平均', u'逐日降水'],{ u'逐日平均':'td', u'逐日降水':'rd'} 
            iFrom,iEnd= \ 
                int(form['Start Year'].value)*10000+ int(form['Start Month'].value)*100+ int(form['Start Day'].value), \ 
                int(form['End Year'].value)*10000+ int(form['End Month'].value)*100+ int(form['End Day'].value) # value from form is string! 
 
            MapParameter=GetMapParameter() 
            if (u'温度' == form['Data Source'].value): 
                d=u'逐日平均' 
                tmpDataTxt='Test_temp.txt' 
                tmpOutPNG='./static/'+'Test_temp.png' 
                MapParameter['LevelFile']='.\maplev_temp.LEV' 
                MapParameter['Title']=u'逐日平均' 
            elif (u'降水(mm)' == form['Data Source'].value):  
                d=u'逐日降水' 
                tmpDataTxt='Test_pred.txt' 
                tmpOutPNG='./static/'+'Test_temp.png' 
                MapParameter['LevelFile']='.\maplev_rain.LEV' 
                MapParameter['Title']=u'逐日降水' 
            else: 
                print "form['Data Source'].value=",form['Data Source'].value 
            print "----------- PROCESSING FOR CATEGORY:",d 
            tmpMeanVal=[] 
            for i in range(len(StationsId)): 
                s,lo,la=StationsId[i],StationsLon[i],StationsLat[i] 
                #print basedir,d, str(s),DataCatsDict[d]+'.txt' 
                datafile=os.path.join(basedir,d, str(s))+DataCatsDict[d]+'.txt' 
                print datafile,iFrom,iEnd 
                data=getdata.GetData(datafile,iFrom,iEnd) 
                a=np.mean(np.array(data)[:,1])*0.1 
                tmpMeanVal.append([s,lo,la,a]) 
            rec=np.array(tmpMeanVal,dtype=[('int','int'),('float','float')]) 
            print 'Writing data ...' 
            np.savetxt(tmpDataTxt,tmpMeanVal,fmt="%6i %-7.2f %-7.2f %8.2f") 
            print 'Writing data ... Done.' 
            sssss=open(tmpDataTxt,'r') 
            print sssss.read() 
            sssss.close() 
            DrawMapMain(MapParameter,inputfile=tmpDataTxt,imgfile=tmpOutPNG) 
            return render.Reports(tmpOutPNG) 

首先我怀疑plt.figure可能存在内存泄漏问题,所以我在开头和结尾使用了clf,plt.close('all')功能兼备!我什至写了一段测试代码:

if __name__ == "__main__": 
    MapParameter=GetMapParameter() 
    MapParameter['LevelFile']='.\maplev_rain.LEV' 
    MapParameter['Title']=u'逐日降水' 
    for iloop in range(0,10): 
        DrawMapMain(MapParameter,inputfile='Test_pred.txt',imgfile='c:/Test_pred'+str(iloop)+'.png') 
    MapParameter['LevelFile']='.\maplev_temp.LEV' 
    MapParameter['Title']=u'逐日temp' 
    for iloop in range(0,10): 
        DrawMapMain(MapParameter,inputfile='Test_temp.txt',imgfile='c:/Test_temp'+str(iloop)+'.png') 

这段代码工作正常。它是如此有线,有人知道一些线索吗?非常感谢!

请您参考如下方法:

这个问题在评论里有答案:

您使用的是什么 matplotlib 后端?如果您从网络服务器运行东西,您应该使用其中一种非交互式的。例如。导入 matplotlib; matplotlib.use('Agg') 在将 matplotlib.pyplot 导入为 plt 之前。 – Joe Kington 1 月 16 日 17:56

有关 matplotlib 后端的更多信息,请参阅:http://matplotlib.org/faq/usage_faq.html#what-is-a-backend – Joe Kington 1 月 17 日 15:21