3

matplotlib の specgram 関数を使用して、データのスペクトログラムをプロットしています。

Pxx, freqs, bins= mlab.specgram(my_data,NFFT=nFFT,Fs=Fs,detrend=mlab.detrend_linear,noverlap=n_overlap,pad_to=p_to,scale_by_freq=True)

ref の場合、上記の "freqs"、"bins" (つまり、時間)、および "Pxx" の形状は、それぞれ (1025,)、(45510,)、および (1025,45510) です。

ここで、関数パラメーターを定義しました

Fs = 10E6      # Sampling Rate
w_length= 256      # window length
nFFT=2 * w_length
n_overlap=np.fix(w_length/2)
p_to = 8 *w_length

このプロットの周波数範囲 (y 軸) は 0 ~ 5E6 Hz です。それをプロットするとき、たとえば 100E3 Hz から 1E6 など、さまざまな周波数範囲を表示することに関心があります。プロットの ylim を変更しても、カラーバーの制限は変更されません。つまり、この「新しい」周波数範囲の信号値を反映するように更新されません。プロットされたy軸の範囲、つまり周波数範囲の制限を変更することで、それに応じてカラーバーが更新/変更されるようにする方法はありますか?

interp='nearest'
cmap=seismic
fig = plt.figure()
ax1=fig.add_subplot(111)
img1=ax1.imshow(Pxx, interpolation=interp, aspect='auto',extent=extent,cmap=cmap)
ax1.autoscale(enable=True,axis='x',tight=True)
ax1.autoscale(enable=True,axis='y',tight=True)
ax1.set_autoscaley_on(False)
ax1.set_ylim([100E3,1E6])
fig.colorbar(img1)
plt.show()

Pxx の最大値と最小値が、関心のある周波数範囲の上限周波数と下限周波数のそれぞれについてどうにかして見つけられれば、これらの値を使用してカラーバーの制限を設定できると考えました。

img1.set_clim(min_val, max_val) 

一般的に Pxx の最大値と最小値を見つけて、それらのインデックスを返すことができます

import numpy as np
>>> np.unravel_index(Pxx.argmax(),Pxx.shape)
(20, 31805)
>>> np.unravel_index(Pxx.argmin(),Pxx.shape)
(1024, 31347)

対象の周波数範囲に対応する Pxx の値を見つけるにはどうすればよいですか?

たとえば、「freqs」で100E3と1E6がおよそどこにあるかを大まかに見つけるために、次のようなことを行うことができます。を使用して配置されます (そして、各 から最初 (または最後) の値を取得します)...

   fmin_index= [i for i,x in enumerate(freqs) if x >= 100E3][0]
   fmax_index= [i for i,x in enumerate(freqs) if x >= 1000E3][0]

また

   fmin_index= [i for i,x in enumerate(freqs) if x <= 100E3][-1]
   fmax_index= [i for i,x in enumerate(freqs) if x <= 1000E3][-1]

そしたらもしかして

min_val = np.min(Pxx[fmin_index,:])
max_val = np.min(Pxx[fmax_index,:])

そして最後に

img1.set_clim(min_val, max_val)

残念ながら、これはカラーバーの値の範囲が正しく見えないという意味で機能していないようです。上記を行うには、より良い/より簡単に/より正確な方法が必要です。

4

1 に答える 1

1

グラフの制限を変更する代わりに、可能な解決策は、プロットするデータを変更して、そのままにしておくことcolorbarです。pylab環境での最小限の作業例:

#some random data
my_data = np.random.random(2048)

#### Your Code
Fs = 10E6      # Sampling Rate
w_length= 256      # window length
nFFT=2 * w_length
n_overlap=np.fix(w_length/2)
p_to = 8 *w_length

Pxx, freqs, bins= mlab.specgram(my_data,NFFT=nFFT,Fs=Fs,
                                detrend=mlab.detrend_linear,
                                noverlap=n_overlap,
                                pad_to=p_to,scale_by_freq=True)

#find a maximum frequency index
maxfreq = 1E5 #replace by your maximum freq
if maxfreq:
    lastfreq = freqs.searchsorted(maxfreq)
    if lastfreq > len(freqs):
        lastfreq = len(freqs)-1

Pxx = np.flipud(Pxx) #flipping image in the y-axis

interp='nearest'
seismic = plt.get_cmap('seismic')
cmap=seismic
fig = plt.figure()
ax1=fig.add_subplot(111)
extent = 0,4,freqs[0],freqs[lastfreq] # new extent
#plot reduced range
img1=ax1.imshow(Pxx[-lastfreq:], interpolation=interp, aspect='auto',
                extent=extent ,cmap=cmap)
ax1.set_autoscaley_on(False)
fig.colorbar(img1)
plt.show()

私の例では最大頻度のみを設定していますが、いくつかの小さな調整により、最小頻度を設定できます。

于 2013-03-06T13:04:07.503 に答える