repos/TB065

Commits Files Refs
commit d9dc016f96dad58c96a349496431b952b65f2c0b
parent 844f0022ea373db8824af84b68bd311afc8aa406
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date:   Wed, 22 Oct 2025 13:47:02 -0300

Updated `tp/**`

Diffstat:
Mtp/main.py | 190++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mtp/plot/a4_clarinete.png | 0
Mtp/plot/a4_flauta.png | 0
Mtp/plot/a4_violin.png | 0
Mtp/plot/cancion1.png | 0
Mtp/plot/cancion1_0_248s_a_0_256s.png | 0
Atp/plot/cancion1_0_520s_a_0_528s.png | 0
Dtp/plot/cancion1_0_52s_a_0_528s.png | 0
Atp/plot/cancion1_espectograma.png | 0
Atp/plot/cancion1_fft.png | 0
Mtp/plot/cancion1_filter1_output_compare.png | 0
Dtp/plot/cancion1_filter1_output_compare_0_248_a_0_256.png | 0
Atp/plot/cancion1_filter1_output_fft.png | 0
Dtp/plot/cancion1_filter2_output_compare.png | 0
Dtp/plot/cancion1_filter2_output_compare_0_248_a_0_256.png | 0
Atp/plot/cancion1_filter2_output_fft.png | 0
Atp/plot/cancion2.png | 0
Mtp/plot/cancion2_14_72s_a_14_73s.png | 0
Mtp/plot/cancion2_26_57s_a_26_58s.png | 0
Dtp/plot/cancion2_6s.png | 0
Dtp/plot/cancion2_6s_filter1_output_compare.png | 0
Dtp/plot/cancion2_6s_filter1_output_compare_26_57_a_26_58.png | 0
Dtp/plot/cancion2_6s_filter2_output_compare.png | 0
Dtp/plot/cancion2_6s_filter2_output_compare_26_57_a_26_58.png | 0
Atp/plot/cancion2_espectograma.png | 0
Atp/plot/cancion2_fft.png | 0
Atp/plot/cancion2_filter1_output_fft.png | 0
Atp/plot/cancion2_filter2_output_fft.png | 0
Atp/plot/filter1_h_fft.png | 0
Atp/plot/filter2_h_fft.png | 0
Mtp/utils.py | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
31 files changed, 223 insertions(+), 109 deletions(-)
diff --git a/tp/main.py b/tp/main.py
@@ -1,8 +1,9 @@
-import matplotlib.pyplot as plt
 import numpy as np
 from scipy.io import wavfile
 from utils import *
 
+## Datos
+
 file1_path          = 'data/cancion1.wav'
 file2_path          = 'data/cancion2.wav'
 filter1_h_file_path = 'data/respuesta_impulso_1.txt'
@@ -18,96 +19,109 @@ file2_fs, file2_data = wavfile.read(file2_path)
 filter1_h = np.loadtxt(filter1_h_file_path)
 filter2_h = np.loadtxt(filter2_h_file_path)
 
-# 'cancion1'
-print(f'"{file1_path}", {file1_fs} Hz')
-
-## grafico completo
-plot(file1_fs, file1_data, file1_path)
-
-## porciones cuasi-periodicas 'cancion1'
-plot(file1_fs, file1_data, file1_path,
-           t_start=0.248, t_width=0.008, a=0.24978, da=0.003)
-
-plot(file1_fs, file1_data, file1_path,
-           t_start=0.520, t_width=0.008, a=0.5208, da=0.003)
-
-## salida de filtro 'cancion1'
 file1_filter1_output = np.convolve(file1_data, filter1_h, mode='same')
 file1_filter2_output = np.convolve(file1_data, filter2_h, mode='same')
 
-save_convolved_to_wav(file1_filter1_output, file1_fs, "file1_filter1_output.wav")
-save_convolved_to_wav(file1_filter2_output, file1_fs, "file1_filter2_output.wav")
-
-## generar grafico comparando la muestra 1 original y filtrada 1
-data_arr = [normalize(file1_data), normalize(file1_filter1_output)]
-leg_arr = ['Señal de audio', 'Señal de audio filtrada']
-
-fig, ax = plot_multiple(file1_fs, data_arr, leg_arr)
-save_plot(fig, file1_path, extra_name="_filter1_output_compare")
-
-fig, ax = plot_multiple(file1_fs, data_arr, leg_arr, t=0.248, dt=0.008)
-save_plot(fig, file1_path, extra_name="_filter1_output_compare_0_248_a_0_256")
-
-## generar grafico comparando la muestra 1 original y filtrada 2
-data_arr = [normalize(file1_data), normalize(file1_filter2_output)]
-leg_arr = ['Señal de audio', 'Señal de audio filtrada']
-
-fig, ax = plot_multiple(file1_fs, data_arr, leg_arr)
-save_plot(fig, file1_path, extra_name="_filter2_output_compare")
-
-fig, ax = plot_multiple(file1_fs, data_arr, leg_arr, t=0.248, dt=0.008)
-save_plot(fig, file1_path, extra_name="_filter2_output_compare_0_248_a_0_256")
-
-# 'cancion2'
-print(f'"{file2_path}", {file2_fs} Hz')
-
-## grafico completo
-plot(file2_fs, file2_data, file2_path, t_start=6)
-
-## porciones cuasi-periodicas 'cancion2'
-plot(file2_fs, file2_data, file2_path, t_start=14.720, t_width=0.01)
-plot(file2_fs, file2_data, file2_path, t_start=26.570, t_width=0.01)
-
-## salida de filtro 'cancion2'
 file2_filter1_output = np.convolve(file2_data, filter1_h, mode='same')
 file2_filter2_output = np.convolve(file2_data, filter2_h, mode='same')
 
-save_convolved_to_wav(file2_filter1_output, file2_fs, "file2_filter1_output.wav")
-save_convolved_to_wav(file2_filter2_output, file2_fs, "file2_filter2_output.wav")
-
-## generar grafico comparando la muestra 2 original y filtrada 2
-data_arr = [normalize(file2_data), normalize(file2_filter1_output)]
-leg_arr = ['Señal original', 'Señal filtrada']
-
-fig, ax = plot_multiple(file2_fs, data_arr, leg_arr, t=6)
-save_plot(fig, file2_path, t_start=6, extra_name="_filter1_output_compare")
-
-fig, ax = plot_multiple(file2_fs, data_arr, leg_arr, t=26.57, dt=0.01)
-save_plot(fig, file2_path, t_start=6,
-          extra_name="_filter1_output_compare_26_57_a_26_58")
-
-## generar grafico comparando la muestra 2 original y filtrada 2
-data_arr = [normalize(file2_data), normalize(file2_filter2_output)]
-leg_arr = ['Señal original', 'Señal filtrada']
-
-fig, ax = plot_multiple(file2_fs, data_arr, leg_arr, t=6)
-save_plot(fig, file2_path, t_start=6, extra_name="_filter2_output_compare")
-
-fig, ax = plot_multiple(file2_fs, data_arr, leg_arr, t=26.57, dt=0.01)
-save_plot(fig, file2_path, t_start=6,
-          extra_name="_filter2_output_compare_26_57_a_26_58")
-
-# Sonido de instrumentos musicales
-a4_flauta_fs, a4_flauta_data = wavfile.read(a4_flauta_file_path)
-a4_clarinete_fs, a4_clarinete_data = wavfile.read(a4_clarinete_file_path)
-a4_violin_fs, a4_violin_data = wavfile.read(a4_violin_file_path)
-
-## grafico de los instrumentos musicales
-fig, ax = plot(a4_flauta_fs, a4_flauta_data, t_start=0.25, t_width=0.010)
-save_plot(fig, a4_flauta_file_path)
-
-fig, ax = plot(a4_clarinete_fs, a4_clarinete_data, t_start=0.25, t_width=0.010)
-save_plot(fig, a4_clarinete_file_path)
-
-fig, ax = plot(a4_violin_fs, a4_violin_data, t_start=0.25, t_width=0.010)
-save_plot(fig, a4_violin_file_path)
+## 'cancion1'
+def time_domain_cancion1():
+    ### grafico completo
+    time_plot(file1_fs, file1_data, file1_path)
+
+    ### porciones cuasi-periodicas 'cancion1'
+    time_plot(file1_fs, file1_data, "cancion1_0_248s_a_0_256s",
+               t_start=0.248, t_width=0.008, a=0.24978, da=0.003)
+
+    time_plot(file1_fs, file1_data, "cancion1_0_520s_a_0_528s",
+               t_start=0.520, t_width=0.008, a=0.5208, da=0.003)
+
+    ### salida de filtro 'cancion1'
+    save_convolved_to_wav(file1_filter1_output, file1_fs, "file1_filter1_output.wav")
+    save_convolved_to_wav(file1_filter2_output, file1_fs, "file1_filter2_output.wav")
+
+    ### grafico comparando la muestra 1 original y filtrada 1
+    data_arr = [normalize(file1_data), normalize(file1_filter1_output)]
+    leg_arr = ['Señal de audio', 'Señal de audio filtrada']
+
+    time_plot_multiple(file1_fs, data_arr, leg_arr, "cancion1_filter1_output_compare.png")
+    time_plot_multiple(file1_fs, data_arr, leg_arr, "cancion1_filter1_output_compare_0_248_a_0_256", t=0.248, dt=0.008)
+
+    ### grafico comparando la muestra 1 original y filtrada 2
+    data_arr = [normalize(file1_data), normalize(file1_filter2_output)]
+    leg_arr = ['Señal de audio', 'Señal de audio filtrada']
+
+    time_plot_multiple(file1_fs, data_arr, leg_arr, "cancion1_filter2_output_compare")
+    time_plot_multiple(file1_fs, data_arr, leg_arr,
+                       "cancion1_filter2_output_compare_0_248_a_0_256", t=0.248, dt=0.008)
+
+## 'cancion2'
+def time_domain_cancion2():
+    ### grafico completo
+    time_plot(file2_fs, file2_data, "cancion2", t_start=6)
+
+    ### porciones cuasi-periodicas 'cancion2'
+    time_plot(file2_fs, file2_data, "cancion2_14_72s_a_14_73s", t_start=14.720, t_width=0.01)
+    time_plot(file2_fs, file2_data, "cancion2_26_57s_a_26_58s", t_start=26.570, t_width=0.01)
+
+    save_convolved_to_wav(file2_filter1_output, file2_fs, "file2_filter1_output.wav")
+    save_convolved_to_wav(file2_filter2_output, file2_fs, "file2_filter2_output.wav")
+
+    ### grafico comparando la muestra 2 original y filtrada 2
+    data_arr = [normalize(file2_data), normalize(file2_filter1_output)]
+    leg_arr = ['Señal original', 'Señal filtrada']
+
+    time_plot_multiple(file2_fs, data_arr, leg_arr, "cancion2_6s_filter1_output_compare", t=6)
+    time_plot_multiple(file2_fs, data_arr, leg_arr, "cancion2_6s_filter1_output_compare_26_57_a_26_58", t=26.57, dt=0.01)
+
+    ### grafico comparando la muestra 2 original y filtrada 2
+    data_arr = [normalize(file2_data), normalize(file2_filter2_output)]
+    leg_arr = ['Señal original', 'Señal filtrada']
+
+    time_plot_multiple(file2_fs, data_arr, leg_arr, "cancion2_6s_filter2_output_compare", t=6)
+    time_plot_multiple(file2_fs, data_arr, leg_arr, "cancion2_6s_filter2_output_compare_26_57_a_26_58", t=26.57, dt=0.01)
+
+def time_domain_music_instruments():
+    ## Sonido de instrumentos musicales
+    a4_flauta_fs, a4_flauta_data = wavfile.read(a4_flauta_file_path)
+    a4_clarinete_fs, a4_clarinete_data = wavfile.read(a4_clarinete_file_path)
+    a4_violin_fs, a4_violin_data = wavfile.read(a4_violin_file_path)
+
+    ### grafico de los instrumentos musicales
+    time_plot(a4_flauta_fs, a4_flauta_data, "a4_flauta", t_start=0.25, t_width=0.010)
+    time_plot(a4_clarinete_fs, a4_clarinete_data, "a4_clarinete", t_start=0.25, t_width=0.010)
+    time_plot(a4_violin_fs, a4_violin_data, "a4_violin", t_start=0.25, t_width=0.010)
+
+def time_domain():
+    time_domain_cancion1()
+    time_domain_cancion2()
+    time_domain_music_instruments()
+
+def freq_domain_cancion1():
+    freq_plot(file1_fs, file1_data, "cancion1_fft", f_max=8000, y_max=1e8)
+    freq_plot(file1_fs, file1_filter1_output, "cancion1_filter1_output_fft",
+              f_max=8000, y_max=1e8)
+    freq_plot(file1_fs, file1_filter2_output, "cancion1_filter2_output_fft",
+              f_max=8000, y_max=1e8)
+
+def freq_domain_cancion2():
+    freq_plot(file2_fs, file2_data, "cancion2_fft",
+              f_max=8000, y_max=0.5e8)
+    freq_plot(file2_fs, file2_filter1_output, "cancion2_filter1_output_fft",
+              f_max=8000, y_max=0.5e8)
+    freq_plot(file2_fs, file2_filter2_output, "cancion2_filter2_output_fft",
+              f_max=8000, y_max=0.5e8)
+
+def freq_domain():
+    freq_domain_cancion1()
+    freq_domain_cancion2()
+
+    freq_plot(48000, filter1_h, "filter1_h_fft", f_max=2000)
+    freq_plot(48000, filter2_h, "filter2_h_fft", f_max=8000)
+
+    spectogram_plot(file1_fs, file1_data, "cancion1_espectograma")
+    spectogram_plot(file2_fs, file2_data, "cancion2_espectograma", t=6)
+
+time_domain()
+freq_domain()
diff --git a/tp/plot/a4_clarinete.png b/tp/plot/a4_clarinete.png
Binary files differ.
diff --git a/tp/plot/a4_flauta.png b/tp/plot/a4_flauta.png
Binary files differ.
diff --git a/tp/plot/a4_violin.png b/tp/plot/a4_violin.png
Binary files differ.
diff --git a/tp/plot/cancion1.png b/tp/plot/cancion1.png
Binary files differ.
diff --git a/tp/plot/cancion1_0_248s_a_0_256s.png b/tp/plot/cancion1_0_248s_a_0_256s.png
Binary files differ.
diff --git a/tp/plot/cancion1_0_520s_a_0_528s.png b/tp/plot/cancion1_0_520s_a_0_528s.png
Binary files differ.
diff --git a/tp/plot/cancion1_0_52s_a_0_528s.png b/tp/plot/cancion1_0_52s_a_0_528s.png
Binary files differ.
diff --git a/tp/plot/cancion1_espectograma.png b/tp/plot/cancion1_espectograma.png
Binary files differ.
diff --git a/tp/plot/cancion1_fft.png b/tp/plot/cancion1_fft.png
Binary files differ.
diff --git a/tp/plot/cancion1_filter1_output_compare.png b/tp/plot/cancion1_filter1_output_compare.png
Binary files differ.
diff --git a/tp/plot/cancion1_filter1_output_compare_0_248_a_0_256.png b/tp/plot/cancion1_filter1_output_compare_0_248_a_0_256.png
Binary files differ.
diff --git a/tp/plot/cancion1_filter1_output_fft.png b/tp/plot/cancion1_filter1_output_fft.png
Binary files differ.
diff --git a/tp/plot/cancion1_filter2_output_compare.png b/tp/plot/cancion1_filter2_output_compare.png
Binary files differ.
diff --git a/tp/plot/cancion1_filter2_output_compare_0_248_a_0_256.png b/tp/plot/cancion1_filter2_output_compare_0_248_a_0_256.png
Binary files differ.
diff --git a/tp/plot/cancion1_filter2_output_fft.png b/tp/plot/cancion1_filter2_output_fft.png
Binary files differ.
diff --git a/tp/plot/cancion2.png b/tp/plot/cancion2.png
Binary files differ.
diff --git a/tp/plot/cancion2_14_72s_a_14_73s.png b/tp/plot/cancion2_14_72s_a_14_73s.png
Binary files differ.
diff --git a/tp/plot/cancion2_26_57s_a_26_58s.png b/tp/plot/cancion2_26_57s_a_26_58s.png
Binary files differ.
diff --git a/tp/plot/cancion2_6s.png b/tp/plot/cancion2_6s.png
Binary files differ.
diff --git a/tp/plot/cancion2_6s_filter1_output_compare.png b/tp/plot/cancion2_6s_filter1_output_compare.png
Binary files differ.
diff --git a/tp/plot/cancion2_6s_filter1_output_compare_26_57_a_26_58.png b/tp/plot/cancion2_6s_filter1_output_compare_26_57_a_26_58.png
Binary files differ.
diff --git a/tp/plot/cancion2_6s_filter2_output_compare.png b/tp/plot/cancion2_6s_filter2_output_compare.png
Binary files differ.
diff --git a/tp/plot/cancion2_6s_filter2_output_compare_26_57_a_26_58.png b/tp/plot/cancion2_6s_filter2_output_compare_26_57_a_26_58.png
Binary files differ.
diff --git a/tp/plot/cancion2_espectograma.png b/tp/plot/cancion2_espectograma.png
Binary files differ.
diff --git a/tp/plot/cancion2_fft.png b/tp/plot/cancion2_fft.png
Binary files differ.
diff --git a/tp/plot/cancion2_filter1_output_fft.png b/tp/plot/cancion2_filter1_output_fft.png
Binary files differ.
diff --git a/tp/plot/cancion2_filter2_output_fft.png b/tp/plot/cancion2_filter2_output_fft.png
Binary files differ.
diff --git a/tp/plot/filter1_h_fft.png b/tp/plot/filter1_h_fft.png
Binary files differ.
diff --git a/tp/plot/filter2_h_fft.png b/tp/plot/filter2_h_fft.png
Binary files differ.
diff --git a/tp/utils.py b/tp/utils.py
@@ -10,6 +10,8 @@ import numpy as np
 import os
 
 from scipy.io import wavfile
+from scipy.fft import fft, fftfreq
+from scipy.signal import spectrogram
 
 plot_dir_name = 'plot'
 out_dir_name = 'out'
@@ -24,7 +26,7 @@ def ticks_label_format(x, pos):
     # 3 decimales, se eliminan los ceros y puntos
     return f"{x:.3f}".rstrip("0").rstrip(".")
 
-def graph_multiple_data(x, y_arr, y_lab, t=0, dt=0, a=0, da=0, show=True):
+def time_graph_multiple_data(x, y_arr, y_lab, t=0, dt=0, a=0, da=0, show=True):
     figure, axis = plt.subplots(figsize=(8, 4))
 
     for i, y in enumerate(y_arr):
@@ -63,12 +65,16 @@ def graph_multiple_data(x, y_arr, y_lab, t=0, dt=0, a=0, da=0, show=True):
     return figure, axis
 
 # todos deben la misma cantidad de elementos que el primero
-def plot_multiple(fs, data_arr, leg_arr, t=0, dt=0, a=0, da=0):
+def time_plot_multiple(fs, data_arr, leg_arr, save_name="", t=0, dt=0, a=0, da=0, show=False):
     x = np.arange(len(data_arr[0])) / fs
-    fig, ax = graph_multiple_data(x, data_arr, leg_arr, t=t, dt=dt, a=a, da=da, show=False)
+    fig, ax = time_graph_multiple_data(x, data_arr, leg_arr, t=t, dt=dt, a=a, da=da, show=show)
+
+    if show == False:
+        save_plot(fig, "cancion1_filter1_output_compare.png")
+
     return fig, ax
 
-def graph_data(x, y, t=0, dt=0, a=0, da=0, show=True):
+def time_graph_data(x, y, t=0, dt=0, a=0, da=0, show=True):
     figure, axis = plt.subplots(figsize=(8, 4))
 
     axis.plot(x, y, label='Señal de audio')
@@ -109,36 +115,36 @@ def normalize(data):
     data /= np.max(np.abs(data))
     return data
 
-def plot(fs, data, file_path="", t_start=0, t_width=0, a=0, da=0):
+def time_plot(fs, data, save_name="", t_start=0, t_width=0, a=0, da=0):
     # normaliza la amplitud dividiendo por el valor maximo del tipo de dato
     data = normalize(data)
 
     t = np.arange(len(data)) / fs
-    fig, ax = graph_data(t, data, t=t_start, dt=t_width, a=a, da=da, show=False)
+    fig, ax = time_graph_data(t, data, t=t_start, dt=t_width, a=a, da=da, show=False)
 
-    if file_path != "":
-        save_plot(fig, file_path, t_start=t_start, t_width=t_width)
+    if save_name != "":
+        save_plot(fig, save_name)
 
     return fig, ax
 
-def save_plot(fig, src_file_path, t_start=0, t_width=0, extra_name=''):
-    basename = os.path.basename(src_file_path)
-    file_name, ext = os.path.splitext(basename)
-    fig_file_name = f'{plot_dir_name}/{file_name}'
-
-    if t_start != 0:
-        fig_name_append_1 = f'_{t_start}s'
-        fig_name_append_2 = f'_a_{round(t_start + t_width, 3)}s' if t_width != 0 else ''
-        fig_file_name += fig_name_append_1.replace('.', '_')
-        fig_file_name += fig_name_append_2.replace('.', '_')
+def save_plot(fig, name):
+    base_name = os.path.basename(name)
+    file_name, ext = os.path.splitext(base_name)
+    file_path_no_ext = f'{plot_dir_name}/{file_name}'
 
-    fig_file_name += extra_name
+    save_name = f'{file_path_no_ext}.png'
+    # if os.path.exists(save_name):
+    #     i = 0
+    #     while os.path.exists(f'{file_path_no_ext}_{i}.png'):
+    #         i += 1
 
-    print(f'- "{fig_file_name}.png"')
+    #     save_name = f'{file_path_no_ext}_{i}.png'
 
+    print(f'- "{save_name}"')
      # crea carpeta para plots
     os.makedirs(plot_dir_name, exist_ok=True)
-    fig.savefig(fig_file_name, dpi=100, bbox_inches="tight")
+    fig.savefig(save_name, dpi=500, bbox_inches="tight")
+    plt.close(fig) # liberar memoria
 
 def save_convolved_to_wav(convolved, fs, file_path):
     # normalizar para prevenir clipping
@@ -154,3 +160,97 @@ def save_convolved_to_wav(convolved, fs, file_path):
     print(f'- "{file_path}"')
     wavfile.write(file_path, fs, convolved_int16)
 
+# frecuencia
+
+def freq_graph_data(x, y, f_min=0, f_max=0, y_min=0, y_max=0, show=True, save_path=""):
+    fig, axis = plt.subplots(figsize=(8, 4))
+
+    axis.plot(x, y, label='Señal de audio')
+    axis.set(xlabel='Frecuencia [Hz]', ylabel='Magnitud normalizada')
+
+    axis.minorticks_on()
+    axis.grid(True, which='major', color='black', linestyle=':', linewidth=1.00)
+    axis.grid(True, which='minor', color='black', linestyle=':', linewidth=0.50)
+
+    # configuracion de ticks del eje x
+    axis.xaxis.set_major_locator(MaxNLocator(nbins=5))
+    axis.xaxis.set_minor_locator(AutoMinorLocator(5))
+
+    axis.yaxis.set_major_locator(MaxNLocator(nbins=5))
+    axis.yaxis.set_minor_locator(AutoMinorLocator(4))
+
+    plt.tight_layout()
+
+    # max 3 decimales
+    axis.xaxis.set_major_formatter(FuncFormatter(ticks_label_format))
+
+    axis.set_xlim([f_min, f_max if f_max != 0 else 20000])
+    axis.set_ylim([y_min, y_max if y_max != 0 else 1.05*max(y)])
+
+    if show:
+        plt.show()
+
+    return fig, axis
+
+# hace la transformacion a frecuencias y pasa lo transformado a `freq_graph_data`
+def freq_plot(fs, data, save_name="", f_min=0, f_max=0, y_min=0, y_max=0,
+              t=0, dt=0, a=0, da=0):
+
+    i = 0
+    di = fs*len(data)
+    if t != 0 or dt != 0:
+        i = int(t*fs)
+        di = int((t+dt)*fs)
+
+    interval_data = data[i:di]
+    N = len(interval_data)
+    interval_fft = fft(interval_data)
+    interval_freqs = fftfreq(N, d=1/fs)
+
+    # se toma la parte positiva en ambos casos (primer parte del arreglo)
+    x = interval_freqs[:N // 2]
+    y = np.abs(interval_fft[:N // 2])
+
+    fig, ax = freq_graph_data(x, y, f_min, f_max, y_min, y_max, show=False)
+
+    if save_name != "":
+        save_plot(fig, save_name)
+
+    return fig, ax
+
+
+from datetime import datetime
+
+def spectogram_plot(fs, data, save_name="", t=0, dt=0, xlim=[], ylim=[], show=False):
+    if dt == 0:
+        dt = (len(data)/fs)-t
+
+    i = int(t*fs)
+    di = int((t+dt)*fs)
+    interval_data = data[i:di]
+
+    f, time, Sxx = spectrogram(interval_data, fs=fs, nperseg=4096, noverlap=32)
+    fig, axis = plt.subplots(figsize=(8, 4))
+
+    plt.pcolormesh(time, f, Sxx**0.10, shading='gouraud')
+    plt.ylabel('Frecuencia [Hz]')
+    plt.xlabel('Tiempo [s]')
+
+    if len(xlim) != 0:
+        plt.xlim(xlim)
+
+    if len(ylim) != 0:
+        plt.ylim(ylim)
+    else:
+        plt.ylim(1, 20000)
+
+    if show == True:
+        plt.show()
+    else:
+        if save_name == "":
+            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+            save_name = f"spectogram_{timestamp}"
+
+        save_plot(fig, save_name)
+
+    return fig, axis