0

I'm trying to convert the x-axis ticks from samples to time in the format mm:ss.decimals. The idea is that one second contains fs=44100 samples, so the conversion should be something like

time.strftime('%S.{}'.format(sample/44.1%1000), time.gmtime(sample/44.1/1000.0)))

Here's the whole code:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
import time
import os
import librosa

filename = 'path_to_your_waveform'
s, fs = librosa.load(filename, sr=44100, mono=False)
s=s[0,0:2*fs]

formatter = matplotlib.ticker.FuncFormatter(lambda sample, x: time.strftime('%S.{}'.format(sample/44.1%1000), time.gmtime(sample/44.1/1000.0)))

t_tot = np.arange(0, len(s), 1)
fig, axs = plt.subplots(2, 1, figsize=(10, 10))
for i in np.arange(0,2,1):

    plt.rcParams["agg.path.chunksize"] = 10000
    axs[i].plot(t_tot, s, color='b', linestyle='-')
    axs[i].xaxis.set_major_locator(MultipleLocator(fs/2))
    axs[i].xaxis.set_major_formatter(formatter)

plt.savefig(os.path.join(os.getcwd(), 'name'))

In the figure below you can see that the x-axis ticks do not make sense (the whole file is cut to exactly 2 seconds).

enter image description here

Phys
  • 508
  • 3
  • 11
  • 22
  • Please try to explain the idea behind `time.strftime('%M:%S:{}'.format(ms%fs), time.gmtime(ms//fs))`. This will either directly lead you to see where you're wrong, or at least allow someone to answer this. – ImportanceOfBeingErnest Oct 17 '19 at 12:11
  • I have just added this part. – Phys Oct 17 '19 at 12:31
  • Not sure I understand the logic. Why is it not something like `time.strftime('%M:%S:%f', time.gmtime(ms/fs))`? – ImportanceOfBeingErnest Oct 17 '19 at 12:48
  • It might be closer to the solution, but it is shown on the plot like 00:00:f – Phys Oct 17 '19 at 12:56
  • Apparently I'm not the only one with the same issue: https://stackoverflow.com/questions/48215948/python-display-milliseconds-in-formatted-string-using-time-strftime – Phys Oct 17 '19 at 13:04
  • My post has been marked has duplicate, even though the solution in the other post does not work for my case and does not contain the plot ticks part. – Phys Oct 17 '19 at 13:09
  • You may show inside the question in how far it does not work. – ImportanceOfBeingErnest Oct 17 '19 at 13:11
  • It's already in there, I get exactly the same plot with the wrong time division. – Phys Oct 17 '19 at 13:15
  • Yeah, but `('%Y-%m-%d %H:%M:%S:{}'.format(time_in_ms%1000), time.gmtime(time_in_ms/1000.0))` is not the same as what you have in the question, right? So no wonder it gives wrong output. – ImportanceOfBeingErnest Oct 17 '19 at 13:19
  • I'm using this one: formatter = matplotlib.ticker.FuncFormatter(lambda ms, x: time.strftime('%S.{}'.format(ms), time.gmtime(ms//fs))) – Phys Oct 17 '19 at 13:24
  • Yes. If you don't see the difference, maybe start by not naming the input `ms`, because it's not milliseconds. That may make it clearer where you're wrong. – ImportanceOfBeingErnest Oct 17 '19 at 13:32
  • Changed 'ms' to 'sample'. – Phys Oct 17 '19 at 13:35
  • Right. So now you see that while the correct solution needs time in milliseconds, you use sample numbers. So you need to convert sample numbers to milliseconds to apply the duplicate answer. – ImportanceOfBeingErnest Oct 17 '19 at 13:39
  • The x-axis is correctly divided now, even if it still shows the wrong format (i.e. 01.500.0 instead of just 01.500) – Phys Oct 17 '19 at 14:18
  • `"{}".format(int(x))` or maybe better `"{:03d}".format(int(x))` – ImportanceOfBeingErnest Oct 17 '19 at 14:50
  • That seems to delete the seconds and leave the decimals only. – Phys Oct 17 '19 at 15:13
  • The original question itself is answered in the duplicate. What you're asking in the comments (or after several edits of the original question) is just how to format a float as an integer in python. There are duplicates for that as well. You can sure ask a new question, but remove librosa and matplotlib from it, i.e. boil it down to the *actual* problem. – ImportanceOfBeingErnest Oct 17 '19 at 15:46

0 Answers0