def test_spectrogram(self): """ Create spectrogram plotting examples in tests/output directory. """ # Create dynamic test_files to avoid dependencies of other modules. # set specific seed value such that random numbers are reproducible np.random.seed(815) head = { 'network': 'BW', 'station': 'BGLD', 'starttime': UTCDateTime(2007, 12, 31, 23, 59, 59, 915000), 'sampling_rate': 200.0, 'channel': 'EHE'} tr = Trace(data=np.random.randint(0, 1000, 824), header=head) st = Stream([tr]) # 1 - using log=True reltol = 1 if MATPLOTLIB_VERSION < [1, 2, 0]: reltol = 2000 with ImageComparison(self.path, 'spectrogram_log.png', reltol=reltol) as ic: with warnings.catch_warnings(record=True): warnings.resetwarnings() np_err = np.seterr(all="warn") spectrogram.spectrogram(st[0].data, log=True, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False) np.seterr(**np_err) # 2 - using log=False reltol = 1 if MATPLOTLIB_VERSION < [1, 3, 0]: reltol = 3 with ImageComparison(self.path, 'spectrogram.png', reltol=reltol) as ic: spectrogram.spectrogram(st[0].data, log=False, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False)
def test_spectogram(self): """ Create spectogram plotting examples in tests/output directory. """ # Create dynamic test_files to avoid dependencies of other modules. # set specific seed value such that random numbers are reproduceable np.random.seed(815) head = { 'network': 'BW', 'station': 'BGLD', 'starttime': UTCDateTime(2007, 12, 31, 23, 59, 59, 915000), 'sampling_rate': 200.0, 'channel': 'EHE'} tr = Trace(data=np.random.randint(0, 1000, 824), header=head) st = Stream([tr]) # 1 - using log=True with NamedTemporaryFile(suffix='.png') as tf: spectrogram.spectrogram(st[0].data, log=True, outfile=tf.name, samp_rate=st[0].stats.sampling_rate, show=False) # compare images expected_image = os.path.join(self.path, 'spectogram_log.png') compare_images(tf.name, expected_image, 0.001) # 2 - using log=False with NamedTemporaryFile(suffix='.png') as tf: spectrogram.spectrogram(st[0].data, log=False, outfile=tf.name, samp_rate=st[0].stats.sampling_rate, show=False) # compare images expected_image = os.path.join(self.path, 'spectogram.png') compare_images(tf.name, expected_image, 0.001)
def test_spectrogram(self, image_path): """ Create spectrogram plotting examples in tests/output directory. """ # Create dynamic test_files to avoid dependencies of other modules. # set specific seed value such that random numbers are reproducible np.random.seed(815) head = { 'network': 'BW', 'station': 'BGLD', 'starttime': UTCDateTime(2007, 12, 31, 23, 59, 59, 915000), 'sampling_rate': 200.0, 'channel': 'EHE' } tr = Trace(data=np.random.randint(0, 1000, 824), header=head) st = Stream([tr]) # 1 - using log=True image_path_1 = image_path.parent / 'spectrogram1.png' with warnings.catch_warnings(record=True): warnings.resetwarnings() with np.errstate(all='warn'): spectrogram.spectrogram(st[0].data, log=True, outfile=image_path_1, samp_rate=st[0].stats.sampling_rate, show=False) # 2 - using log=False image_path_2 = image_path.parent / 'spectrogram2.png' spectrogram.spectrogram(st[0].data, log=False, outfile=image_path_2, samp_rate=st[0].stats.sampling_rate, show=False)
def test_spectogram(self): """ Create spectogram plotting examples in tests/output directory. """ # Create dynamic test_files to avoid dependencies of other modules. # set specific seed value such that random numbers are reproduceable np.random.seed(815) head = {'network': 'BW', 'station': 'BGLD', 'starttime': UTCDateTime(2007, 12, 31, 23, 59, 59, 915000), 'sampling_rate': 200.0, 'channel': 'EHE'} tr = Trace(data=np.random.randint(0, 1000, 824), header=head) st = Stream([tr]) # 1 - using log=True outfile = os.path.join(self.path, 'spectogram_log.png') spectrogram.spectrogram(st[0].data, log=True, outfile=outfile, samp_rate=st[0].stats.sampling_rate, show=False) # check that outfile was modified stat = os.stat(outfile) self.assertTrue(abs(stat.st_mtime - time.time()) < 3) # 2 - using log=False outfile = os.path.join(self.path, 'spectogram.png') spectrogram.spectrogram(st[0].data, log=False, outfile=outfile, samp_rate=st[0].stats.sampling_rate, show=False) # check that outfile was modified stat = os.stat(outfile) self.assertTrue(abs(stat.st_mtime - time.time()) < 3)
def spectrogram(ar, header, freq, tr='auto', verbose=True): """ Displays a spectrogram of the center trace of the array. This is for testing purposes and not accessible from the command prompt. :param numpy.ndarray ar: The radar array :param dict header: The file header dictionary :type tr: int or str :param tr: The trace to display the spectrogram for. Defaults to "auto" but can be an integer representing the trace number to plot. "auto" will pick a trace roughly halfway through the array. :param bool verbose: Verbose, defaults to False """ import obspy.imaging.spectrogram as sg # buried here, to avoid obspy compatibility issues if tr == 'auto': tr = int(ar.shape[1] / 2) if verbose: fx.printmsg( 'converting trace %s to frequency domain and drawing spectrogram...' % (tr)) samp_rate = header['samp_freq'] trace = ar.T[tr] sg.spectrogram( data=trace, samp_rate=samp_rate, wlen=samp_rate / 1000, per_lap=0.99, dbscale=True, title= 'Trace %s Spectrogram - Antenna Frequency: %.2E Hz - Sampling Frequency: %.2E Hz' % (tr, freq, samp_rate))
def test_spectrogram_nice_error_messages(self): """ Make sure to have some nice messages on weird input """ # Only 20 samples at 1 Hz and our default tries to window 128 samples, # so we dont even have enough data for a single window. This used to # fail inside mlab specgram with ugly error message about the input data = np.ones(20) msg = ('Input signal too short (20 samples, window length 6.4 ' 'seconds, nfft 128 samples, sampling rate 20.0 Hz)') with pytest.raises(ValueError) as e: spectrogram.spectrogram(data, samp_rate=20.0, show=False) assert str(e.value) == msg # Only 130 samples at 1 Hz and our default tries to window 128 samples, # so we dont have enough data for two windows. In principle we could # still plot that but our code currently relies on having at least two # windows for plotting. It does not seem worthwhile to change the code # to do so, so just show a nice error data = np.ones(130) msg = ('Input signal too short (130 samples, window length 6.4 ' 'seconds, nfft 128 samples, 115 samples window overlap, ' 'sampling rate 20.0 Hz)') with pytest.raises(ValueError) as e: spectrogram.spectrogram(data, samp_rate=20.0, show=False) assert str(e.value) == msg plt.close('all')
def Receiver2GradientSpectrogram(Receiver, AmplitudeList, yLabel="", **kwargs): timePre = np.asarray(Receiver.Time) AmplitudePre = np.asarray(AmplitudeList) TimeIdx = timePre.argsort() time = timePre[TimeIdx] Amplitude = AmplitudePre[TimeIdx] Amplitude = np.asarray(pd.Series(np.gradient(Amplitude, time).tolist())) samplingrate = len(Amplitude)/time.max() AxOut = kwargs.get("ax",None) if AxOut == None: fig = plt.figure(figsize = (10, 5),dpi=300, constrained_layout=True) gs = fig.add_gridspec(1, 1) ax = fig.add_subplot(gs[:, :]) fig.suptitle('Spectrogram, st {}'.format(Receiver.Coord)) else: kwargs.pop("ax") ax = AxOut ax2 = ax.twinx() spectrogram.spectrogram(Amplitude,samplingrate,log=True,axes=ax,show=False,**kwargs) ax.set_ylabel("Frequency [Hz]") ax.set_xlabel("time [s]") mappable = ax.collections[0] cbaxes = inset_axes(ax,width="40%",height="4%",loc=1, borderpad=2) plt.colorbar(mappable=mappable, cax=cbaxes, orientation="horizontal", label="Amplitude spectrum") cbaxes.ticklabel_format(axis='both', style='sci', scilimits=(0,0)) cbaxes.xaxis.set_label_position('top') cbaxes.xaxis.label.set_color('white') cbaxes.tick_params(labelcolor='white') ax2.plot(time, Amplitude, lw=1, c='k') #ax2.ticklabel_format(axis='both', style='sci', scilimits=(0,0)) ax2.set_ylim([0,9]) ax2.set_ylabel(yLabel) if AxOut == None: return fig, ax, ax2 else: return ax, ax2
def plotSpectrogram(tr1,highCut): print('plotting Spectrogram....') Data=tr1.data samplingFreq=tr1.stats.sampling_rate N = len(Data) # Number of samplepoints xN=np.linspace(1, (N/samplingFreq), N) #xN = np.divide(xN, 60) t1 = np.divide(xN, (samplingFreq*60)) fig = plt.figure() fig.canvas.set_window_title('FFT Spectrum ' + str(tr1.stats.starttime.date)) ax1 = fig.add_axes([0.1, 0.75, 0.7, 0.2]) #[left bottom width height] ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.60], sharex=ax1) ax3 = fig.add_axes([0.83, 0.1, 0.03, 0.6]) #ax2.set_ylim([1.0,3.0]) # t = np.arange(spl1[0].stats.N) / spl1[0].stats.sampling_rate ax1.plot(xN, Data, 'k') #ax,spec = spectrogram(Data, samplingFreq, show=False, axes=ax2) ax = spectrogram(Data, samplingFreq, show=False, axes=ax2) mappable = ax2.images[0] plt.colorbar(mappable=mappable, cax=ax3) ax1.set_ylabel(r'$\Delta$ P - Pa') ax2.set_ylabel(r'f - Hz', fontsize=14) ax2.set_xlabel(r'$\Delta$t - s', fontsize=12) #ax2.set_ylim([0.0,6]) ax2.set_ybound(lower=None, upper=(highCut*2.0)) fig.show()
def test_spectrogram_defaults(self): """ Make sure input at varying sampling rates and data lengths does not suffer from defaults (wlen etc) being calculated to nonsensical values resulting in errors raised from the underlying mlab spectrogram wlen (in s) used to be calculated as (samp_rate / 100) which makes no sense, it results in very large window sizes for high sampling rates and in window lengths that dont even include a two samples for low sampling rates like 1 Hz. """ # input of 30 minutes sampled at 1 Hz should definitely be able to have # a sensible default for window length, but it used to fail data = np.ones(1800) spectrogram.spectrogram(data, samp_rate=1, show=False) plt.close('all')
def test_spectogram(self): """ Create spectogram plotting examples in tests/output directory. """ # Create dynamic test_files to avoid dependencies of other modules. # set specific seed value such that random numbers are reproduceable np.random.seed(815) head = { 'network': 'BW', 'station': 'BGLD', 'starttime': UTCDateTime(2007, 12, 31, 23, 59, 59, 915000), 'sampling_rate': 200.0, 'channel': 'EHE' } tr = Trace(data=np.random.randint(0, 1000, 824), header=head) st = Stream([tr]) # 1 - using log=True with ImageComparison(self.path, 'spectogram_log.png') as ic: with warnings.catch_warnings(record=True) as w: warnings.resetwarnings() np_err = np.seterr(all="warn") spectrogram.spectrogram(st[0].data, log=True, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False) np.seterr(**np_err) self.assertEqual(len(w), 2) self.assertEqual(w[0].category, UserWarning) self.assertEqual( str(w[0].message), 'aspect is not supported for Axes with ' 'xscale=linear, yscale=log') self.assertEqual(w[1].category, RuntimeWarning) self.assertEqual(str(w[1].message), 'underflow encountered in multiply') # 2 - using log=False reltol = 1 if MATPLOTLIB_VERSION < [1, 3, 0]: reltol = 3 with ImageComparison(self.path, 'spectogram.png', reltol=reltol) as ic: spectrogram.spectrogram(st[0].data, log=False, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False)
def spectrogram(ar, header, freq, verbose=True): """ displays a spectrogram of the center trace of the array this is for testing purposes and not accessible from the command prompt """ tr = int(ar.shape[1] / 2) if verbose: fx.printmsg( 'converting trace %s to frequency domain and drawing spectrogram...' % (tr)) samp_rate = 1 / (header['rhf_depth'] / header['cr'] / header['rh_nsamp']) trace = ar.T[tr] sg.spectrogram( data=trace, samp_rate=samp_rate, wlen=samp_rate / 1000, per_lap=0.99, dbscale=True, title= 'Trace %s Spectrogram - Antenna Frequency: %.2E Hz - Sampling Frequency: %.2E Hz' % (tr, freq, samp_rate))
def test_spectrogram(self): """ Create spectrogram plotting examples in tests/output directory. """ # Create dynamic test_files to avoid dependencies of other modules. # set specific seed value such that random numbers are reproduceable np.random.seed(815) head = { 'network': 'BW', 'station': 'BGLD', 'starttime': UTCDateTime(2007, 12, 31, 23, 59, 59, 915000), 'sampling_rate': 200.0, 'channel': 'EHE'} tr = Trace(data=np.random.randint(0, 1000, 824), header=head) st = Stream([tr]) # 1 - using log=True with ImageComparison(self.path, 'spectrogram_log.png') as ic: with warnings.catch_warnings(record=True) as w: warnings.resetwarnings() np_err = np.seterr(all="warn") spectrogram.spectrogram(st[0].data, log=True, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False) np.seterr(**np_err) self.assertEqual(len(w), 2) self.assertEqual(w[0].category, UserWarning) self.assertEqual(str(w[0].message), 'aspect is not supported for Axes with ' 'xscale=linear, yscale=log') self.assertEqual(w[1].category, RuntimeWarning) self.assertEqual(str(w[1].message), 'underflow encountered in multiply') # 2 - using log=False reltol = 1 if MATPLOTLIB_VERSION < [1, 3, 0]: reltol = 3 with ImageComparison(self.path, 'spectrogram.png', reltol=reltol) as ic: spectrogram.spectrogram(st[0].data, log=False, outfile=ic.name, samp_rate=st[0].stats.sampling_rate, show=False)
def test_spectogram(self): """ Create spectogram plotting examples in tests/output directory. """ # Create dynamic test_files to avoid dependencies of other modules. # set specific seed value such that random numbers are reproduceable np.random.seed(815) head = { 'network': 'BW', 'station': 'BGLD', 'starttime': UTCDateTime(2007, 12, 31, 23, 59, 59, 915000), 'sampling_rate': 200.0, 'channel': 'EHE' } tr = Trace(data=np.random.randint(0, 1000, 824), header=head) st = Stream([tr]) # 1 - using log=True with NamedTemporaryFile(suffix='.png') as tf: spectrogram.spectrogram(st[0].data, log=True, outfile=tf.name, samp_rate=st[0].stats.sampling_rate, show=False) # compare images expected_image = os.path.join(self.path, 'spectogram_log.png') compare_images(tf.name, expected_image, 0.001) # 2 - using log=False with NamedTemporaryFile(suffix='.png') as tf: spectrogram.spectrogram(st[0].data, log=False, outfile=tf.name, samp_rate=st[0].stats.sampling_rate, show=False) # compare images expected_image = os.path.join(self.path, 'spectogram.png') compare_images(tf.name, expected_image, 0.001)
def plot(self, stream, color): for trace in stream: timeArray = np.arange(0, trace.stats.npts) timeArray = timeArray * 1 / trace.stats.sampling_rate timeArray = timeArray + trace.stats.starttime.timestamp # Check if the data is a ma.maskedarray if np.ma.count_masked(trace.data): timeArray = np.ma.array(timeArray[:-1], mask=trace.data.mask) if self.dataAxes.images: self.dataAxes.images.pop() spectrogram(trace.data, samp_rate=trace.stats.sampling_rate, axes=self.dataAxes) extent = self.dataAxes.images[0].get_extent() newExtent = (extent[0] + trace.stats.starttime.timestamp, extent[1] + trace.stats.starttime.timestamp, extent[2], extent[3]) self.dataAxes.images[0].set_extent(newExtent) self.dataAxes.set_frame_on(False)
ax1.tick_params(axis='x', which='both', labelsize=0) ax1.set_ylabel('normalised\namplitude\n', fontsize=12) ax1.get_yaxis().set_label_coords(-0.08, 0.5) plt.title(str.upper(catalogue) + ' : ' + event[:-6], fontsize=12, y=1.1) ## Generate spectrogram for combined seismogram and add to figure print 'Generating spectrogram plots for station ' + station ax2 = plt.subplot(412) spectrogram(np.array(seismogram), samp_rate=sampling_rate, per_lap=0.99, wlen=1.0, cmap='jet', axes=ax2) ax2.set_xlim(3, rel_time[-1] - 1.5) ax2.set_yticks([0, 40, 80, 120]) # HARDCODE !!! ax2.spines['top'].set_visible(True) ax2.spines['right'].set_visible(True) ax2.yaxis.set_ticks_position('both') ax2.xaxis.set_ticks_position('both') ax2.tick_params(which='both', direction='out') ax2.tick_params(which='both', length=5) ax2.tick_params(which='both', width=1.1) ax2.tick_params(axis='x', which='both', labelsize=0) ax2.set_ylabel('frequency\n(Hz)\n', fontsize=12) ax2.get_yaxis().set_label_coords(-0.08, 0.5)
t1 = tr.stats.starttime.timestamp t2 = tr.stats.endtime.timestamp x_lim = list(map(datetime.utcfromtimestamp, [t1, t2])) x_lims = dates.date2num(x_lim) y_lims = [0, 100] fig, (ax0, ax1) = plt.subplots(nrows=2) #fig.set_size_inches(28,12) spectrogram(tr.data, tr.stats.sampling_rate, wlen=wlen, per_lap=per_lap, clip=clip, mult=mult, axes=ax0, dbscale=True, log=False, cmap='jet', title=str(tr.stats.station) + " " + str(tr.stats.starttime)) #tr.spectrogram(log=True, axes=ax0, title=tr.stats.station + " " + str(tr.stats.starttime), mult=8.0, wlen=5.0, per_lap=0.9, clip=clip) #custom_spectro.spectrogram(data=tr.data,samp_rate=tr.stats.sampling_rate,log=False,cmap='jet', dbscale=True, show=False,clip=clip, axes=ax0, wlen=wlen,per_lap=per_lap,decal=0) ax0.xaxis.set_major_locator(MultipleLocator(60)) ax0.xaxis.set_minor_locator(MultipleLocator(30)) ax0.set_ylim(0, tr.stats.sampling_rate / 2) ax0.set_xlim(0, duration) ax0.set_title("%s [%s - %s]" % (tr.stats.station, x_lim[0], x_lim[1])) ax1.plot(tr.times("matplotlib"), tr.data, "b-", linewidth=0.5)