specgram () does all the work for you. If you look in axes.py in the specgram function, you will see how it works. The original function is on Python27\Lib\site-packages\matplotlib\axes.py on my computer.
<snip> Pxx, freqs, bins = mlab.specgram(x, NFFT, Fs, detrend, window, noverlap, pad_to, sides, scale_by_freq) 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 = self.imshow(Z, cmap, extent=extent, **kwargs) self.axis('auto') return Pxx, freqs, bins, im
You may need to create your own function modeled on this and copy the Pxx data according to your needs.
Pxx, freqs, bins = mlab.specgram(x, NFFT, Fs, detrend, window, noverlap, pad_to, sides, scale_by_freq) # **************** # create a new limited Pxx and freqs # # **************** Z = 10. * np.log10(Pxx) Z = np.flipud(Z)
Pxx is a 2d array with the form (len (freqs), len (bins)
>>> Pxx.shape (129, 311) >>> freqs.shape (129,) >>> bins.shape (311,) >>>
This will limit Pxx and freqs.
Pxx = Pxx[(freqs >= 125) & (freqs <= 1000)] freqs = freqs[(freqs >= 125) & (freqs <= 1000)]
Here is the complete solution - my_specgram () - used with specgram_demo from the gallery .
from pylab import * from matplotlib import * # 100, 400 and 200 Hz sine 'wave' dt = 0.0005 t = arange(0.0, 20.0, 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 NFFT = 1024 # 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 (ie 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) # the minfreq and maxfreq args will limit the frequencies Pxx, freqs, bins, im = my_specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900, cmap=cm.Accent, minfreq = 180, maxfreq = 220) show() close()