调用matplotlib AFTER多处理后有时会导致错误:主线程不在主循环中

时间:2018-10-29 12:14:50

标签: python matplotlib tkinter python-multiprocessing concurrent.futures

我正在做一些多处理,并且我想了解为什么有时以下代码段(但从来没有在循环的第一次迭代中)生成 以下错误:

   Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7f6c40d25ba8>>
    Traceback (most recent call last):
      File "/usr/lib/python3.5/tkinter/__init__.py", line 3359, in __del__
        self.tk.call('image', 'delete', self.name)
    RuntimeError: main thread is not in main loop
    Tcl_AsyncDelete: async handler deleted by the wrong thread
    Traceback (most recent call last):
      File "Analize0.py", line 94, in <module>
        Lambda = np.array(Rescal.multiprocess_loop_grouped(grouped_spatial_lambda, range(Nalti), Group_size, N_thread, *args))
      File "/home/gadal/PythonLib_perso/Rescal/Lib_Rescal.py", line 135, in multiprocess_loop_grouped
        return [dic[i] for i in sorted(dic.keys())]
      File "/home/gadal/PythonLib_perso/Rescal/Lib_Rescal.py", line 135, in <listcomp>
        return [dic[i] for i in sorted(dic.keys())]
      File "<string>", line 2, in __getitem__
      File "/usr/lib/python3.5/multiprocessing/managers.py", line 717, in _callmethod
        kind, result = conn.recv()
      File "/usr/lib/python3.5/multiprocessing/connection.py", line 250, in recv
        buf = self._recv_bytes()
      File "/usr/lib/python3.5/multiprocessing/connection.py", line 407, in _recv_bytes
        buf = self._recv(4)
      File "/usr/lib/python3.5/multiprocessing/connection.py", line 383, in _recv
        raise EOFError
    EOFError

这是代码:

list_per = sorted(glob.glob('Plage*'))
Nper = len(list_per)
for simul_per in list_per :
    print(simul_per)
    path_small = os.getcwd()
    os.chdir(simul_per)
    list_alti = sorted(glob.glob('ALTI00*'))
    Nalti = len(list_alti)
    Group_size = Nalti // N_thread

    print('Reading files ...')
    Map = np.array(Rescal.multiprocess_loop_grouped(Rescal.read_file, list_alti, Group_size, N_thread))

    print('Processing data ...')

    ##################################################################################### Data analysis
    Y_simul = (100, 500)
    Deviation = np.empty((Nalti,Y_simul[1] - Y_simul[0], Map.shape[-1]))
    for i in range(Nalti):  ############### removing average beach topography
        Deviation[i,:,:] = Map[i,Y_simul[0]:Y_simul[1],:] - np.mean(Map[i,Y_simul[0]:Y_simul[1],:], axis = 0, keepdims = True)



    ############   Beach wavelength
    print('     Beach wavelength ...')

    X_beach = (300,650)

    args = [X_beach, Deviation]
    Temp = Rescal.multiprocess_loop_grouped(find_lambda_plage, range(Nalti), Group_size, N_thread, *args)
    Lambda_plage = np.array([i[0] for i in Temp])
    Orientation = np.array([i[1] for i in Temp])

    ############ Wavelength as a function of space
    print('     Wavelength as a function of space ...')

    args = [Deviation]
    Lambda = np.array(Rescal.multiprocess_loop_grouped(grouped_spatial_lambda, range(Nalti), Group_size, N_thread, *args))

    print('Saving data ...')

    Data = {}
    Data['Lambda_finger'] = Lambda_finger
    Data['Lambda_plage'] = Lambda_plage
    Data['Orientation'] = Orientation
    Data['Map'] = Map
    Data['Lambda'] = Lambda

    np.save('Data', Data)

    print('Saving figures ...')

    plt.figure()
    plt.plot(Lambda_finger)
    plt.ylim([0, 300])
    plt.savefig('Lambda_finger.pdf')

    plt.clf()
    plt.plot(Lambda_plage)
    plt.plot(Lambda_finger[:,10])
    plt.ylim([0, 300])
    plt.legend(('Lambda plage', 'Lambda finger'))
    plt.savefig('Lambda.pdf')

    plt.clf()
    plt.imshow(Lambda)
    cbar = plt.colorbar()
    plt.xlabel('x')
    plt.ylabel('Time')
    cbar.set_label('Lambda')
    plt.clim([0, 80])
    plt.savefig('Spatial_time_lambda.pdf')


    plt.close('all')

    os.chdir(path_small)

我正在使用我编写的函数对我拥有的文件执行一些独立的任务,该函数在此处进行介绍:Function that multiprocesses another function

但是,由多进程调用的函数永远不会调用matplotlib,在最后一次多进程调用完成后,主线程会调用matplotlib。

例如,上一个错误grouped_spatial_lambda中的函数由以下组成:

def spatial_evolution_lambda(Map):
    Lambda = []
    for x in range(Map.shape[1]):
        Lambda.append(Anls.find_first_max(autocorr(Map[:,x])))
    return Lambda

def grouped_spatial_lambda(indexes,dic,Deviation):
    for i in indexes:
        dic[i] = spatial_evolution_lambda(Deviation[i,:,:])

def find_first_max(a, valmax = False):
    inds = find_peaks(a)[0]
    if len(inds) > 0:
        l = inds[inds > 5]
        if len(l) > 0:
            testerr = 0
            a_norm = a/np.max(a)
            x_fit = np.array([i for i in range(int(l[0]/2), int(3*l[0]/2))])
            x_fit = x_fit[x_fit < len(a)]
            y_fit = a_norm[x_fit]
            x_fit = x_fit[y_fit > 0]
            y_fit = a_norm[x_fit]
            if x_fit.size == 0 or len(x_fit) < 3 :
                lamb = np.nan
                amp = np.nan
            else:
                try:
    #                popt, pcov = curve_fit(gaus,x_fit.ravel(),y_fit.ravel(), p0=[np.max(y_fit),np.mean(x_fit),np.mean(x_fit)])
                    popt, pcov = curve_fit(gaus,x_fit,y_fit, p0=[np.max(y_fit),np.mean(x_fit),np.mean(x_fit)])

                except RuntimeError:
                    lamb =  np.nan
                    amp = np.nan
                    testerr = 1
                if testerr == 0:
                    lamb =  popt[1]
                    amp = popt[0]
        else:
            lamb = np.nan
            amp = np.nan
    else:
        lamb =  np.nan
        amp = np.nan
    if valmax == False:
        return lamb
    else:
        return lamb, amp, 1.96/np.sqrt(a.size)

根据我从发布的错误中了解到的信息,tkinter会生成导致EOF错误的异常?在对其他函数进行多重处理之后,对matplotlib的调用又如何呢?它与循环有关吗? (先前调用matplotlib ..?) 如何强制matplotlib在主线程中运行?

0 个答案:

没有答案