我正在使用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”,“bin”(即时间)和“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]
OR
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)
不幸的是,在颜色条上的值范围看起来不正确的情况下,这似乎不起作用。必须有更好/更容易/更准确的方法来完成上述任务。
答案 0 :(得分: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()
我的示例仅设置最大频率,但通过一些小的调整,您可以设置最小值。