2015-04-02 113 views
1

我是新來發布問題,並嘗試遵循適當的禮儀,所以請幫助我從我的問題中的任何遺漏或錯誤中學習。python matplotlib specgram()最大繪圖值顯示不正確

我正在使用specgram來分析聲音信號,並對結果的兩個方面感到困惑。

  1. 圖解似乎有放置在箱陣列,這是應該最後箱的中間中的最後一個值的時間頻譜的端部。我希望劇情結束於最後一個垃圾桶的結束的值。

  2. 作爲時間軸返回的bin中心值看起來與Matlab中的值不同,但可能有一個參數設置在我的試驗中不同。

這些問題出現的Matplotlib的例子之一,從:http://matplotlib.org/1.4.0/examples/pylab_examples/specgram_demo.html

倉值是:0.256,0.768,1.28 ... ..19.2,19.712。

最明顯的問題是譜圖的圖結束於19.712,而不是預期值20.0。

任何人都可以請澄清?這些問題中的任何一個似乎都代表了一個錯誤?或者我做錯了什麼?提前How to make specgram fill entire figure area with matplotlib?

感謝您能提供任何指導:

這涉及到這個問題。

回答

0

是的,該圖確實在最後一個箱的中間結束。這可能是不正確的。

但是,無論如何,它不會是2.0,原因有二。

首先,端點很少會與上一個樣本完美匹配,因爲它被分成NFFT長度段,有noverlap的重疊,除非您非常仔細地挑選,否則不太可能完全適合信號的長度信號長度,分段長度和重疊。

即使這樣,它也永遠不會去20.0,因爲numpy arange與其他python範圍一樣,排除了最後一個值。所以t.max()20.0-dt,這是19.9995。再次,這只是一個不同於MATLAB使用的約定。

使用MATLAB 2014b和譜圖函數,我使用與matplotlib示例相同的參數運行它,確保考慮範圍的終點。我得到了與matplotlib相同的時間點。

+0

OK,點取有關預期斌中心。我確實理解有關段長度等問題。我可能在Matlab和matplotlib之間有不匹配的參數。謝謝。繪圖縮放仍然是一個問題。我正在尋找解決方法。在Matlab中,我將採集數據,然後使用imagesc()重繪自己。我一直在努力從specgram()返回Pxx或im值,並將它們繪製在一個新窗口中。我無法理解「範圍」和「方面」的論點。任何有關如何以正確的時間縮放重新繪製數據的指針將非常感激。 – 2015-04-02 16:11:15

+0

你可以看看matplotlib的github網站上'specgram'方法的源代碼,以瞭解它是如何實現的https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes/_axes.py 。除此之外,在這裏問一個新問題可能會更好。 – TheBlackCat 2015-04-03 07:31:14

0

請看看:Cutting of unused frequencies in specgram matplotlib

下面是上面使用不同的參數的版本說明他們的影響:

from pylab import * 
    from matplotlib import * 
    # 100, 200, and 400 Hz sine 'wave' 
    # Using more sample points 
    dt = 0.00005 
    t = arange(0.0, 20.000, dt) 
    s1 = sin(2*pi*100*t) 
    s2 = 2*sin(2*pi*400*t) 
    s3 = 2*sin(2*pi*200*t)

# create a transient "chirp" 
mask = where(logical_and(t>10, t<12), 1.0, 0.0) 
s2 = s2 * mask 

# add some noise into the mix 
nse = 0.01*randn(len(t)) 

x = s1 + s2 + +s3 + nse # the signal 
#x = s1 + s2 + nse # the signal 
# Longer window 
NFFT = 2048  # the length of the windowing segments 
Fs = int(1.0/dt) # the sampling frequency 

# modified specgram() 
def my_specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, 
      window=mlab.window_hanning, noverlap=128, 
      cmap=None, xextent=None, pad_to=None, sides='default', 
      scale_by_freq=None, minfreq = None, maxfreq = None, **kwargs): 
    """ 
    call signature:: 

     specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, 
       window=mlab.window_hanning, noverlap=128, 
       cmap=None, xextent=None, pad_to=None, sides='default', 
       scale_by_freq=None, minfreq = None, maxfreq = None, **kwargs) 

    Compute a spectrogram of data in *x*. Data are split into 
    *NFFT* length segments and the PSD of each section is 
    computed. The windowing function *window* is applied to each 
    segment, and the amount of overlap of each segment is 
    specified with *noverlap*. 

    %(PSD)s 

     *Fc*: integer 
     The center frequency of *x* (defaults to 0), which offsets 
     the y extents of the plot to reflect the frequency range used 
     when a signal is acquired and then filtered and downsampled to 
     baseband. 

     *cmap*: 
     A :class:`matplotlib.cm.Colormap` instance; if *None* use 
     default determined by rc 

     *xextent*: 
     The image extent along the x-axis. xextent = (xmin,xmax) 
     The default is (0,max(bins)), where bins is the return 
     value from :func:`mlab.specgram` 

     *minfreq, maxfreq* 
     Limits y-axis. Both required 

     *kwargs*: 

     Additional kwargs are passed on to imshow which makes the 
     specgram image 

     Return value is (*Pxx*, *freqs*, *bins*, *im*): 

     - *bins* are the time points the spectrogram is calculated over 
     - *freqs* is an array of frequencies 
     - *Pxx* is a len(times) x len(freqs) array of power 
     - *im* is a :class:`matplotlib.image.AxesImage` instance 

    Note: If *x* is real (i.e. non-complex), only the positive 
    spectrum is shown. If *x* is complex, both positive and 
    negative parts of the spectrum are shown. This can be 
    overridden using the *sides* keyword argument. 

    **Example:** 

    .. plot:: mpl_examples/pylab_examples/specgram_demo.py 

    """ 

    ##################################### 
    # modified axes.specgram() to limit 
    # the frequencies plotted 
    ##################################### 

    # this will fail if there isn't a current axis in the global scope 
    ax = gca() 
    Pxx, freqs, bins = mlab.specgram(x, NFFT, Fs, detrend, 
     window, noverlap, pad_to, sides, scale_by_freq) 

    # modified here 
    ##################################### 
    if minfreq is not None and maxfreq is not None: 
     Pxx = Pxx[(freqs >= minfreq) & (freqs <= maxfreq)] 
     freqs = freqs[(freqs >= minfreq) & (freqs <= maxfreq)] 
    ##################################### 

    Z = 10. * np.log10(Pxx) 
    Z = np.flipud(Z) 

    if xextent is None: xextent = 0, np.amax(bins) 
    xmin, xmax = xextent 
    freqs += Fc 
    extent = xmin, xmax, freqs[0], freqs[-1] 
    im = ax.imshow(Z, cmap, extent=extent, **kwargs) 
    ax.axis('auto') 

    return Pxx, freqs, bins, im 

# plot 
ax1 = subplot(211) 
plot(t, x) 
subplot(212, sharex=ax1) 
# Windowing+greater overlap + limiting bandwidth to plot: 
# the minfreq and maxfreq args will limit the frequencies 
Pxx, freqs, bins, im = my_specgram(x, NFFT=NFFT, Fs=Fs, noverlap=2000, window=numpy.kaiser(NFFT,1.0), cmap=cm.gist_heat, minfreq = 0, maxfreq = 1000) 
show() 
close()