2012-06-28 57 views
0

我寫這將打開紫外 - 可見光譜,並試圖用大筆的功能,以適應他們一個Python腳本。但是,我希望在發現最小殘差時將擬合步驟顯示在圖中。計算器實際上有一些例子,這種想法(http://stackoverflow.com/questions/4098131/matplotlib-update-a-plot)接觸,但由於某種原因,這種做法是不工作對我來說非常好。我的意思是「工作不太好」,即劇情窗口不響應腳本中正在發生的更新。 我曾嘗試我的代碼削減到的東西是更容易理解,還編譯,但也更接近我比的例子的代碼,並顯示如下。如何在裝配功能時更新matplotlib圖形?

要重新短語我的問題:是否有通過擬合過程做這種類型的屏幕刷新的,這樣的窗口不會成爲「(無響應)」的更好的辦法?

這裏是我的簡化代碼:

# import modules that I'm using 
import matplotlib 
matplotlib.use('GTKAgg') 
import Tkinter 
from Tkinter import * 
import numpy as np 
import scipy as sc 
import matplotlib.pyplot as pltlib 
# lmfit is imported becuase parameters are allowed to depend on each other along with bounds, etc. 
from lmfit import minimize, Parameters, Minimizer 

#If button is pressed on the window, open a file and get the data 
def open_File(): 
    # file is opened here and some data is taken 
    # I've just set some arrays here so it will compile alone 
    x=[] 
    y=[] 
    for num in range(0,1000):x.append(num*.001+1) 
    # just some random function is given here, the real data is a UV-Vis spectrum 
    for num2 in range(0,1000):y.append(sc.math.sin(num2*.06)+sc.math.e**(num2*.001)) 
    X = np.array(x) 
    Y = np.array(y) 

    # plot the initial data in one figure 
    pltlib.ion() 
    pltlib.interactive(True) 
    pltlib.figure(1) 
    pltlib.plot(X,Y, "r-") 
    pltlib.show() 

    #deconvolute this initial data into deveral lorentzian profiles 
    deconvolute(X,Y) 

#lorentz line for constructing the more complex function 
def lorentz(x, amp, center, width): 
    return amp*1/sc.math.pi*(width/((x-center)**2+width**2)) 

def deconvolute(X,Y): 
    #make 2nd figure for the refreshing screen 
    deconvFig = pltlib.figure(2) 
    ax = deconvFig.add_subplot(111) 
    line1,line2=ax.plot(X,Y,'r-',X,Y,'r-') 

    # setup parameters for several (here is 30, I potentially hae many more in the real program) 
    params = Parameters() 
    for p in range(0,30): 
     params.add('amp' + str(p), value=1) 
     params.add('center' + str(p), value=1) 
     params.add('width' + str(p), value=1) 

    #get residual function for minimizing 
    def residual(params, X, data=None): 
     model = 0 
     # get values for each lorentz and sum them up 
     for p in range(0,30): 
      amp = params['amp' + str(p)].value 
      center = params['center' + str(p)].value 
      width = params['width' + str(p)].value 
      tmpLorentz = lorentz(X, amp, center, width) 
      model = model + tmpLorentz 

     # This is where the main problem is. 
     # This 2nd figure stops responding after a very small (1?) number of iterations 
     ######################################## 
     # I want redraw the figure at every step through the fitting process 
     line2.set_ydata(model) 
     deconvFig.canvas.draw() 
     print 'screen should be refreshed' 
     ######################################## 

     return (data - model) 

    #fit the function to the data 
    result = minimize(residual, params, args=(X, Y)) 
    print 'done fitting the program' 

#create a window with a button 
MainWindow = Tk() 
Button(text='Open a File', command=open_File).pack(side=BOTTOM) 
MainWindow.mainloop() 

回答

0

有趣,我試圖運行一個簡單的測試。

import time 
from matplotlib import pyplot as pltlib 
deconvFig = pltlib.figure(2) 
ax = deconvFig.add_subplot(111) 
X, Y = range(10), range(10) 
line1,line2 = ax.plot(X,Y,'r-',X,Y,'r-') 
for x in xrange(2, 6, 1): 
    line2.set_ydata(range(0, 10*x, x)) 
    deconvFig.canvas.draw() 
    time.sleep(2) 

>>> import matplotlib 
>>> matplotlib.__version__ 
'1.1.0' 

以及它按預期工作。
也許因爲你產生第二個數字。

import time 
from matplotlib import pyplot as pltlib 

pltlib.ion() 
pltlib.interactive(True) 
pltlib.figure(1) 
pltlib.plot(range(10),range(10), "r-") 
pltlib.show() 

deconvFig = pltlib.figure(2) 
ax = deconvFig.add_subplot(111) 
X, Y = range(10), range(10) 
line1,line2 = ax.plot(X,Y,'r-',X,Y,'r-') 
for x in xrange(2, 6, 1): 
    line2.set_ydata(range(0, 10*x, x)) 
    deconvFig.canvas.draw() 
    time.sleep(2) 

nope仍然正常工作。
這可能是我的設置。

雖然它也有可能是其減少在非常緩慢的速度,所以當你繪製更新你不能分辨出來,就可以計算出RMSE看出差別有多大

print numpy.sqrt(numpy.sum((data - model)**2)/model.shape[0])/numpy.mean(data) * 100 

而且我通常使用SciPy的的最小化功能http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html是它可以最大限度地減少大部分功能,但它的工作原理是隨機突變的輸入,所以我不知道它有多快就可以了,但在許多情況下,許多應用。

我希望這會有所幫助。