0

I am trying to plot the specgram of an array (my_array) sampled at 4,000Hz. In this example, the data were collected on May 15, 2019 over 11 minutes, from 08:41 to 08:52.

I am extracting my data from a csv file using pandas, but for the sake of creating a reprex, I am creating a time array (my_times) of unix timestamps from scratch:

import matplotlib.pyplot as plt
import matplotlib.ticker as tick
import datetime
import numpy as np

SR=4000 #sampling rate

my_times = np.arange(1557909700.221257,1557910338.095864,0.00025)
my_array = np.random.rand(my_times.shape[0])

I would like to plot the specgram (matplotlib.pyplot.specgram) but instead of displaying the number of bins on the abscissa, I would like to represent actual times.

This is my current code, taking inspiration from this SO post:

Pxx, freqs, bins, im=plt.specgram(my_array,Fs=SR, NFFT=8192, scale_by_freq='True', detrend='mean', scale='dB')
ax=plt.gca()
def timeTicks(my_times, pos):                                                                                                                                                                                                                                                         
    return datetime.datetime.utcfromtimestamp(my_times).strftime("%H:%M:%S")                                                                                                                                                                                                                                                                                
formatter = tick.FuncFormatter(timeTicks)   
ax.xaxis.set_major_formatter(formatter) 

plt.ylabel('Frequency (Hz)')
plt.xlabel('Time (hh:mm:ss)')

This code yields the following plot:

enter image description here

My problem is that the times given here start at 00:00. How can I plot the "absolute" time, i.e. have my plot start at 08:42?

I do not really understand how the FuncFormatter works. Any help would be appreciated!

Sheldon
  • 4,084
  • 3
  • 20
  • 41

1 Answers1

0

I ended up using xextent to specify the image extent along the x-axis parameter. I specified the first sample of my time array (my_times[0]) as xmin and the last sample (my_times[0]) as xmax:

Pxx, freqs, bins, im=plt.specgram(my_array,Fs=SR, NFFT=8192, scale_by_freq='True', detrend='mean', scale='dB', xextent=[my_times[0],my_times[-1]])

Modifying the code yielded the following image:

enter image description here

Sheldon
  • 4,084
  • 3
  • 20
  • 41