<reponame>ebeauce/PhaseNet<gh_stars>0
import matplotlib
#matplotlib.use("agg")
import matplotlib.pyplot as plt
import numpy as np
import os


def plot_residual(diff_p, diff_s, diff_ps, tol, dt):
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.07, 0.95]
    plt.figure(figsize=(8,3))
    plt.subplot(1,3,1)
    plt.hist(diff_p, range=(-tol, tol), bins=int(2*tol/dt)+1, facecolor='b', edgecolor='black', linewidth=1)
    plt.ylabel("Number of picks")
    plt.xlabel("Residual (s)")
    plt.text(text_loc[0], text_loc[1], "(i)", horizontalalignment='left', verticalalignment='top',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    plt.title("P-phase")
    plt.subplot(1,3,2)
    plt.hist(diff_s, range=(-tol, tol), bins=int(2*tol/dt)+1, facecolor='b', edgecolor='black', linewidth=1)
    plt.xlabel("Residual (s)")
    plt.text(text_loc[0], text_loc[1], "(ii)", horizontalalignment='left', verticalalignment='top',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    plt.title("S-phase")
    plt.subplot(1,3,3)
    plt.hist(diff_ps, range=(-tol, tol), bins=int(2*tol/dt)+1, facecolor='b', edgecolor='black', linewidth=1)
    plt.xlabel("Residual (s)")
    plt.text(text_loc[0], text_loc[1], "(iii)", horizontalalignment='left', verticalalignment='top',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    plt.title("PS-phase")
    plt.tight_layout()
    plt.savefig("residuals.png", dpi=300)
    plt.savefig("residuals.pdf")


# def plot_waveform(config, data, pred, label=None, 
#                   itp=None, its=None, itps=None,
#                   itp_pred=None, its_pred=None, itps_pred=None,
#                   fname=None, figure_dir="./", epoch=0, max_fig=10):

#     dt = config.dt if hasattr(config, "dt") else 1.0
#     t = np.arange(0, pred.shape[1]) * dt
#     box = dict(boxstyle='round', facecolor='white', alpha=1)
#     text_loc = [0.05, 0.77]
#     if fname is None:
#         fname = [f"{epoch:03d}_{i:02d}" for i in range(len(data))]
#     else:
#         fname = [fname[i].decode().rstrip(".npz") for i in range(len(fname))]
        
#     for i in range(min(len(data), max_fig)):
#         plt.figure(i)
        
#         plt.subplot(411)
#         plt.plot(t, data[i, :, 0, 0], 'k', label='E', linewidth=0.5)
#         plt.autoscale(enable=True, axis='x', tight=True)
#         tmp_min = np.min(data[i, :, 0, 0])
#         tmp_max = np.max(data[i, :, 0, 0])
#         if (itp is not None) and (its is not None):
#             for j in range(len(itp[i])):
#                 lb = "P" if j==0 else ""
#                 plt.plot([itp[i][j]*dt, itp[i][j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
#             for j in range(len(its[i])):
#                 lb = "S" if j==0 else ""
#                 plt.plot([its[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
#         if (itps is not None):
#             for j in range(len(itps[i])):
#                 lb = "PS" if j==0 else ""
#                 plt.plot([itps[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
#         plt.ylabel('Amplitude')
#         plt.legend(loc='upper right', fontsize='small')
#         plt.gca().set_xticklabels([])
#         plt.text(text_loc[0], text_loc[1], '(i)', horizontalalignment='center',
#                  transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        
#         plt.subplot(412)
#         plt.plot(t, data[i, :, 0, 1], 'k', label='N', linewidth=0.5)
#         plt.autoscale(enable=True, axis='x', tight=True)
#         tmp_min = np.min(data[i, :, 0, 1])
#         tmp_max = np.max(data[i, :, 0, 1])
#         if (itp is not None) and (its is not None):
#             for j in range(len(itp[i])):
#                 lb = "P" if j==0 else ""
#                 plt.plot([itp[i][j]*dt, itp[i][j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
#             for j in range(len(its[i])):
#                 lb = "S" if j==0 else ""
#                 plt.plot([its[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
#         if (itps is not None):
#             for j in range(len(itps[i])):
#                 lb = "PS" if j==0 else ""
#                 plt.plot([itps[i][j]*dt, itps[i][j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
#         plt.ylabel('Amplitude')
#         plt.legend(loc='upper right', fontsize='small')
#         plt.gca().set_xticklabels([])
#         plt.text(text_loc[0], text_loc[1], '(ii)', horizontalalignment='center',
#                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        
#         plt.subplot(413)
#         plt.plot(t, data[i, :, 0, 2], 'k', label='Z', linewidth=0.5)
#         plt.autoscale(enable=True, axis='x', tight=True)
#         tmp_min = np.min(data[i, :, 0, 2])
#         tmp_max = np.max(data[i, :, 0, 2])
#         if (itp is not None) and (its is not None):
#             for j in range(len(itp[i])):
#                 lb = "P" if j==0 else ""
#                 plt.plot([itp[i][j]*dt, itp[i][j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
#             for j in range(len(its[i])):
#                 lb = "S" if j==0 else ""
#                 plt.plot([its[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
#         if (itps is not None):
#             for j in range(len(itps[i])):
#                 lb = "PS" if j==0 else ""
#                 plt.plot([itps[i][j]*dt, itps[i][j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
#         plt.ylabel('Amplitude')
#         plt.legend(loc='upper right', fontsize='small')
#         plt.gca().set_xticklabels([])
#         plt.text(text_loc[0], text_loc[1], '(iii)', horizontalalignment='center',
#                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        
#         plt.subplot(414)
#         if label is not None:
#             plt.plot(t, label[i, :, 0, 1], 'C0', label='P', linewidth=1)
#             plt.plot(t, label[i, :, 0, 2], 'C1', label='S', linewidth=1)
#             if label.shape[-1] == 4:
#                 plt.plot(t, label[i, :, 0, 3], 'C2', label='PS', linewidth=1)
#         plt.plot(t, pred[i, :, 0, 1], '--C0', label='$\hat{P}$', linewidth=1)
#         plt.plot(t, pred[i, :, 0, 2], '--C1', label='$\hat{S}$', linewidth=1)
#         if pred.shape[-1] == 4:
#             plt.plot(t, pred[i, :, 0, 3], '--C2', label='$\hat{PS}$', linewidth=1)
#         plt.autoscale(enable=True, axis='x', tight=True)
#         if (itp_pred is not None) and (its_pred is not None) :
#             for j in range(len(itp_pred)):
#                 plt.plot([itp_pred[j]*dt, itp_pred[j]*dt], [-0.1, 1.1], '--C0', linewidth=1)
#             for j in range(len(its_pred)):
#                 plt.plot([its_pred[j]*dt, its_pred[j]*dt], [-0.1, 1.1], '--C1', linewidth=1)
#         if (itps_pred is not None):
#             for j in range(len(itps_pred)):
#                 plt.plot([itps_pred[j]*dt, itps_pred[j]*dt], [-0.1, 1.1], '--C2', linewidth=1)
#         plt.ylim([-0.05, 1.05])
#         plt.text(text_loc[0], text_loc[1], '(iv)', horizontalalignment='center',
#                  transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
#         plt.legend(loc='upper right', fontsize='small', ncol=2)
#         plt.xlabel('Time (s)')
#         plt.ylabel('Probability')
#         plt.tight_layout()
#         plt.gcf().align_labels()

#         try:
#             plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight')
#         except FileNotFoundError:
#             os.makedirs(os.path.dirname(os.path.join(figure_dir, fname[i])), exist_ok=True)
#             plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight')

#         plt.close(i)
#     return 0


def plot_waveform(data, pred, fname, label=None, 
                  itp=None, its=None, itps=None,
                  itp_pred=None, its_pred=None, itps_pred=None,
                  figure_dir="./", dt=0.01):

    t = np.arange(0, pred.shape[0]) * dt
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.05, 0.77]

    plt.figure()
    
    plt.subplot(411)
    plt.plot(t, data[:, 0, 0], 'k', label='E', linewidth=0.5)
    plt.autoscale(enable=True, axis='x', tight=True)
    tmp_min = np.min(data[:, 0, 0])
    tmp_max = np.max(data[:, 0, 0])
    if (itp is not None) and (its is not None):
        for j in range(len(itp)):
            lb = "P" if j==0 else ""
            plt.plot([itp[j]*dt, itp[j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
        for j in range(len(its[i])):
            lb = "S" if j==0 else ""
            plt.plot([its[j]*dt, its[j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
    if (itps is not None):
        for j in range(len(itps)):
            lb = "PS" if j==0 else ""
            plt.plot([itps[j]*dt, its[j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
    plt.ylabel('Amplitude')
    plt.legend(loc='upper right', fontsize='small')
    plt.gca().set_xticklabels([])
    plt.text(text_loc[0], text_loc[1], '(i)', horizontalalignment='center',
                transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    
    plt.subplot(412)
    plt.plot(t, data[:, 0, 1], 'k', label='N', linewidth=0.5)
    plt.autoscale(enable=True, axis='x', tight=True)
    tmp_min = np.min(data[:, 0, 1])
    tmp_max = np.max(data[:, 0, 1])
    if (itp is not None) and (its is not None):
        for j in range(len(itp)):
            lb = "P" if j==0 else ""
            plt.plot([itp[j]*dt, itp[j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
        for j in range(len(its)):
            lb = "S" if j==0 else ""
            plt.plot([its[j]*dt, its[j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
    if (itps is not None):
        for j in range(len(itps)):
            lb = "PS" if j==0 else ""
            plt.plot([itps[j]*dt, itps[j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
    plt.ylabel('Amplitude')
    plt.legend(loc='upper right', fontsize='small')
    plt.gca().set_xticklabels([])
    plt.text(text_loc[0], text_loc[1], '(ii)', horizontalalignment='center',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    
    plt.subplot(413)
    plt.plot(t, data[:, 0, 2], 'k', label='Z', linewidth=0.5)
    plt.autoscale(enable=True, axis='x', tight=True)
    tmp_min = np.min(data[:, 0, 2])
    tmp_max = np.max(data[:, 0, 2])
    if (itp is not None) and (its is not None):
        for j in range(len(itp)):
            lb = "P" if j==0 else ""
            plt.plot([itp[j]*dt, itp[j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
        for j in range(len(its)):
            lb = "S" if j==0 else ""
            plt.plot([its[j]*dt, its[j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
    if (itps is not None):
        for j in range(len(itps)):
            lb = "PS" if j==0 else ""
            plt.plot([itps[j]*dt, itps[j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
    plt.ylabel('Amplitude')
    plt.legend(loc='upper right', fontsize='small')
    plt.gca().set_xticklabels([])
    plt.text(text_loc[0], text_loc[1], '(iii)', horizontalalignment='center',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    
    plt.subplot(414)
    if label is not None:
        plt.plot(t, label[:, 0, 1], 'C0', label='P', linewidth=1)
        plt.plot(t, label[:, 0, 2], 'C1', label='S', linewidth=1)
        if label.shape[-1] == 4:
            plt.plot(t, label[:, 0, 3], 'C2', label='PS', linewidth=1)
    plt.plot(t, pred[:, 0, 1], '--C0', label='$\hat{P}$', linewidth=1)
    plt.plot(t, pred[:, 0, 2], '--C1', label='$\hat{S}$', linewidth=1)
    if pred.shape[-1] == 4:
        plt.plot(t, pred[:, 0, 3], '--C2', label='$\hat{PS}$', linewidth=1)
    plt.autoscale(enable=True, axis='x', tight=True)
    if (itp_pred is not None) and (its_pred is not None) :
        for j in range(len(itp_pred)):
            plt.plot([itp_pred[j]*dt, itp_pred[j]*dt], [-0.1, 1.1], '--C0', linewidth=1)
        for j in range(len(its_pred)):
            plt.plot([its_pred[j]*dt, its_pred[j]*dt], [-0.1, 1.1], '--C1', linewidth=1)
    if (itps_pred is not None):
        for j in range(len(itps_pred)):
            plt.plot([itps_pred[j]*dt, itps_pred[j]*dt], [-0.1, 1.1], '--C2', linewidth=1)
    plt.ylim([-0.05, 1.05])
    plt.text(text_loc[0], text_loc[1], '(iv)', horizontalalignment='center',
                transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    plt.legend(loc='upper right', fontsize='small', ncol=2)
    plt.xlabel('Time (s)')
    plt.ylabel('Probability')
    plt.tight_layout()
    plt.gcf().align_labels()

    try:
        plt.savefig(os.path.join(figure_dir, fname+'.png'), bbox_inches='tight')
    except FileNotFoundError:
        os.makedirs(os.path.dirname(os.path.join(figure_dir, fname)), exist_ok=True)
        plt.savefig(os.path.join(figure_dir, fname+'.png'), bbox_inches='tight')

    plt.close()
    return 0


def plot_array(config, data, pred, label=None,
               itp=None, its=None, itps=None,
               itp_pred=None, its_pred=None, itps_pred=None,
               fname=None, figure_dir="./", epoch=0):

    dt = config.dt if hasattr(config, "dt") else 1.0
    t = np.arange(0, pred.shape[1]) * dt
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.05, 0.95]
    if fname is None:
        fname = [f"{epoch:03d}_{i:03d}" for i in range(len(data))]
    else:
        fname = [fname[i].decode().rstrip(".npz") for i in range(len(fname))]
        
    for i in range(len(data)):
        plt.figure(i, figsize=(10, 5))
        plt.clf()

        plt.subplot(121)
        for j in range(data.shape[-2]):
            plt.plot(t, data[i, :, j, 0]/10 + j, 'k', label='E', linewidth=0.5)
        plt.autoscale(enable=True, axis='x', tight=True)
        tmp_min = np.min(data[i, :, 0, 0])
        tmp_max = np.max(data[i, :, 0, 0])
        plt.xlabel('Time (s)')
        plt.ylabel('Amplitude')
        # plt.legend(loc='upper right', fontsize='small')
        # plt.gca().set_xticklabels([])
        plt.text(text_loc[0], text_loc[1], '(i)', horizontalalignment='center', verticalalignment="top", 
                 transform=plt.gca().transAxes, fontsize="large", fontweight="normal", bbox=box)
        
        plt.subplot(122)
        for j in range(pred.shape[-2]):
            if label is not None:
                plt.plot(t, label[i, :, j, 1]+j, 'C2', label='P', linewidth=0.5)
                plt.plot(t, label[i, :, j, 2]+j, 'C3', label='S', linewidth=0.5)
                # plt.plot(t, label[i, :, j, 0]+j, 'C4', label='N', linewidth=0.5)
            plt.plot(t, pred[i, :, j, 1]+j, 'C0', label='$\hat{P}$', linewidth=1)
            plt.plot(t, pred[i, :, j, 2]+j, 'C1', label='$\hat{S}$', linewidth=1)
            plt.autoscale(enable=True, axis='x', tight=True)
        if (itp_pred is not None) and (its_pred is not None) and (itps_pred is not None):
            for j in range(len(itp_pred)):
                plt.plot([itp_pred[j]*dt, itp_pred[j]*dt], [-0.1, 1.1], '--C0', linewidth=1)
            for j in range(len(its_pred)):
                plt.plot([its_pred[j]*dt, its_pred[j]*dt], [-0.1, 1.1], '--C1', linewidth=1)
            for j in range(len(itps_pred)):
                plt.plot([itps_pred[j]*dt, itps_pred[j]*dt], [-0.1, 1.1], '--C2', linewidth=1)
        # plt.ylim([-0.05, 1.05])
        plt.text(text_loc[0], text_loc[1], '(ii)', horizontalalignment='center', verticalalignment="top", 
                 transform=plt.gca().transAxes, fontsize="large", fontweight="normal", bbox=box)
        # plt.legend(loc='upper right', fontsize='small', ncol=2)
        plt.xlabel('Time (s)')
        plt.ylabel('Probability')
        plt.tight_layout()
        plt.gcf().align_labels()

        try:
            plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight')
        except FileNotFoundError:
            os.makedirs(os.path.dirname(os.path.join(figure_dir, fname[i])), exist_ok=True)
            plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight')

        plt.close(i)
    return 0


def plot_spectrogram(config, data, pred, label=None, 
                     itp=None, its=None, itps=None,
                     itp_pred=None, its_pred=None, itps_pred=None,
                     time=None, freq=None,
                     fname=None, figure_dir="./", epoch=0):

    # dt = config.dt
    # df = config.df
    # t = np.arange(0, data.shape[1]) * dt
    # f = np.arange(0, data.shape[2]) * df
    t, f = time, freq
    dt = t[1] - t[0]
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.05, 0.75]
    if fname is None:
        fname = [f"{i:03d}" for i in range(len(data))]
    elif type(fname[0]) is bytes:
        fname = [f.decode() for f in fname]
        
    numbers = ["(i)", "(ii)", "(iii)", "(iv)"]
    for i in range(len(data)):
        fig = plt.figure(i)
        # gs = fig.add_gridspec(4, 1)
        
        for j in range(3):
            # fig.add_subplot(gs[j, 0])
            plt.subplot(4,1,j+1)
            plt.pcolormesh(t, f, np.abs(data[i, :, :, j]+1j*data[i, :, :, j+3]).T, vmax=2*np.std(data[i, :, :, j]+1j*data[i, :, :, j+3]), cmap="jet", shading='auto')
            plt.autoscale(enable=True, axis='x', tight=True)
            plt.gca().set_xticklabels([])
            if j == 1:
                plt.ylabel('Frequency (Hz)')
            plt.text(text_loc[0], text_loc[1], numbers[j], horizontalalignment='center',
                    transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)

        # fig.add_subplot(gs[-1, 0])
        plt.subplot(4,1,4)
        if label is not None:
            plt.plot(t, label[i, :, 0, 1], '--C0', linewidth=1)
            plt.plot(t, label[i, :, 0, 2], '--C3', linewidth=1)
            plt.plot(t, label[i, :, 0, 3], '--C1', linewidth=1)
        plt.plot(t, pred[i, :, 0, 1], 'C0', label='P', linewidth=1)
        plt.plot(t, pred[i, :, 0, 2], 'C3', label='S', linewidth=1)
        plt.plot(t, pred[i, :, 0, 3], 'C1', label='PS', linewidth=1)
        plt.plot(t, t*0, 'k', linewidth=1)
        plt.autoscale(enable=True, axis='x', tight=True)
        if (itp_pred is not None) and (its_pred is not None) and (itps_pred is not None):
            for j in range(len(itp_pred)):
                plt.plot([itp_pred[j]*dt, itp_pred[j]*dt], [-0.1, 1.1], ':C3', linewidth=1)
            for j in range(len(its_pred)):
                plt.plot([its_pred[j]*dt, its_pred[j]*dt], [-0.1, 1.1], '-.C6', linewidth=1)
            for j in range(len(itps_pred)):
                plt.plot([itps_pred[j]*dt, itps_pred[j]*dt], [-0.1, 1.1], '--C8', linewidth=1)
        plt.ylim([-0.05, 1.05])
        plt.text(text_loc[0], text_loc[1], numbers[-1], horizontalalignment='center',
                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        plt.legend(loc='upper right', fontsize='small', ncol=1)
        plt.xlabel('Time (s)')
        plt.ylabel('Probability')
        # plt.tight_layout()
        plt.gcf().align_labels()

        try:
            plt.savefig(os.path.join(figure_dir, f'{epoch:02d}_'+fname[i]+'.png'), bbox_inches='tight')
        except FileNotFoundError:
            os.makedirs(os.path.dirname(os.path.join(figure_dir, fname[i])), exist_ok=True)
            plt.savefig(os.path.join(figure_dir, f'{epoch:02d}_'+fname[i]+'.png'), bbox_inches='tight')

        plt.close(i)
    return 0


def plot_spectrogram_waveform(config, spectrogram, waveform, pred, label=None, 
                              itp=None, its=None, itps=None, picks=None,
                              time=None, freq=None,
                              fname=None, figure_dir="./", epoch=0):

    # dt = config.dt
    # df = config.df
    # t = np.arange(0, spectrogram.shape[1]) * dt
    # f = np.arange(0, spectrogram.shape[2]) * df
    t, f = time, freq
    dt = t[1] - t[0]
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.02, 0.90]
    if fname is None:
        fname = [f"{i:03d}" for i in range(len(spectrogram))]
    elif type(fname[0]) is bytes:
        fname = [f.decode() for f in fname]
        
    numbers = ["(i)", "(ii)", "(iii)", "(iv)", "(v)", "(vi)", "(vii)"]
    for i in range(len(spectrogram)):
        fig = plt.figure(i, figsize=(6.4, 10))
        # gs = fig.add_gridspec(4, 1)
        
        for j in range(3):
            # fig.add_subplot(gs[j, 0])
            plt.subplot(7,1,j*2+1)
            plt.plot(waveform[i,:,j], 'k', linewidth=0.5)
            plt.autoscale(enable=True, axis='x', tight=True)
            plt.gca().set_xticklabels([])
            plt.ylabel('')
            plt.text(text_loc[0], text_loc[1], numbers[j*2], horizontalalignment='left', verticalalignment='top',
                    transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)

        for j in range(3):
            # fig.add_subplot(gs[j, 0])
            plt.subplot(7,1,j*2+2)
            plt.pcolormesh(t, f, np.abs(spectrogram[i, :, :, j]+1j*spectrogram[i, :, :, j+3]).T, vmax=2*np.std(spectrogram[i, :, :, j]+1j*spectrogram[i, :, :, j+3]), cmap="jet", shading='auto')
            plt.autoscale(enable=True, axis='x', tight=True)
            plt.gca().set_xticklabels([])
            if j == 1:
                plt.ylabel('Frequency (Hz) or Amplitude')
            plt.text(text_loc[0], text_loc[1], numbers[j*2+1], horizontalalignment='left', verticalalignment='top',
                    transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)

        # fig.add_subplot(gs[-1, 0])
        plt.subplot(7,1,7)
        if label is not None:
            plt.plot(t, label[i, :, 0, 1], '--C0', linewidth=1)
            plt.plot(t, label[i, :, 0, 2], '--C3', linewidth=1)
            plt.plot(t, label[i, :, 0, 3], '--C1', linewidth=1)
        plt.plot(t, pred[i, :, 0, 1], 'C0', label='P', linewidth=1)
        plt.plot(t, pred[i, :, 0, 2], 'C3', label='S', linewidth=1)
        plt.plot(t, pred[i, :, 0, 3], 'C1', label='PS', linewidth=1)
        plt.plot(t, t*0, 'k', linewidth=1)
        plt.autoscale(enable=True, axis='x', tight=True)
        plt.ylim([-0.05, 1.05])
        plt.text(text_loc[0], text_loc[1], numbers[-1], horizontalalignment='left', verticalalignment='top',
                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        plt.legend(loc='upper right', fontsize='small', ncol=1)
        plt.xlabel('Time (s)')
        plt.ylabel('Probability')
        # plt.tight_layout()
        plt.gcf().align_labels()

        try:
            plt.savefig(os.path.join(figure_dir, f'{epoch:02d}_'+fname[i]+'.png'), bbox_inches='tight')
        except FileNotFoundError:
            os.makedirs(os.path.dirname(os.path.join(figure_dir, fname[i])), exist_ok=True)
            plt.savefig(os.path.join(figure_dir, f'{epoch:02d}_'+fname[i]+'.png'), bbox_inches='tight')

        plt.close(i)
    return 0

import matplotlib
#matplotlib.use("agg")
import matplotlib.pyplot as plt
import numpy as np
import os


def plot_residual(diff_p, diff_s, diff_ps, tol, dt):
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.07, 0.95]
    plt.figure(figsize=(8,3))
    plt.subplot(1,3,1)
    plt.hist(diff_p, range=(-tol, tol), bins=int(2*tol/dt)+1, facecolor='b', edgecolor='black', linewidth=1)
    plt.ylabel("Number of picks")
    plt.xlabel("Residual (s)")
    plt.text(text_loc[0], text_loc[1], "(i)", horizontalalignment='left', verticalalignment='top',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    plt.title("P-phase")
    plt.subplot(1,3,2)
    plt.hist(diff_s, range=(-tol, tol), bins=int(2*tol/dt)+1, facecolor='b', edgecolor='black', linewidth=1)
    plt.xlabel("Residual (s)")
    plt.text(text_loc[0], text_loc[1], "(ii)", horizontalalignment='left', verticalalignment='top',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    plt.title("S-phase")
    plt.subplot(1,3,3)
    plt.hist(diff_ps, range=(-tol, tol), bins=int(2*tol/dt)+1, facecolor='b', edgecolor='black', linewidth=1)
    plt.xlabel("Residual (s)")
    plt.text(text_loc[0], text_loc[1], "(iii)", horizontalalignment='left', verticalalignment='top',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    plt.title("PS-phase")
    plt.tight_layout()
    plt.savefig("residuals.png", dpi=300)
    plt.savefig("residuals.pdf")


# def plot_waveform(config, data, pred, label=None, 
#                   itp=None, its=None, itps=None,
#                   itp_pred=None, its_pred=None, itps_pred=None,
#                   fname=None, figure_dir="./", epoch=0, max_fig=10):

#     dt = config.dt if hasattr(config, "dt") else 1.0
#     t = np.arange(0, pred.shape[1]) * dt
#     box = dict(boxstyle='round', facecolor='white', alpha=1)
#     text_loc = [0.05, 0.77]
#     if fname is None:
#         fname = [f"{epoch:03d}_{i:02d}" for i in range(len(data))]
#     else:
#         fname = [fname[i].decode().rstrip(".npz") for i in range(len(fname))]
        
#     for i in range(min(len(data), max_fig)):
#         plt.figure(i)
        
#         plt.subplot(411)
#         plt.plot(t, data[i, :, 0, 0], 'k', label='E', linewidth=0.5)
#         plt.autoscale(enable=True, axis='x', tight=True)
#         tmp_min = np.min(data[i, :, 0, 0])
#         tmp_max = np.max(data[i, :, 0, 0])
#         if (itp is not None) and (its is not None):
#             for j in range(len(itp[i])):
#                 lb = "P" if j==0 else ""
#                 plt.plot([itp[i][j]*dt, itp[i][j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
#             for j in range(len(its[i])):
#                 lb = "S" if j==0 else ""
#                 plt.plot([its[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
#         if (itps is not None):
#             for j in range(len(itps[i])):
#                 lb = "PS" if j==0 else ""
#                 plt.plot([itps[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
#         plt.ylabel('Amplitude')
#         plt.legend(loc='upper right', fontsize='small')
#         plt.gca().set_xticklabels([])
#         plt.text(text_loc[0], text_loc[1], '(i)', horizontalalignment='center',
#                  transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        
#         plt.subplot(412)
#         plt.plot(t, data[i, :, 0, 1], 'k', label='N', linewidth=0.5)
#         plt.autoscale(enable=True, axis='x', tight=True)
#         tmp_min = np.min(data[i, :, 0, 1])
#         tmp_max = np.max(data[i, :, 0, 1])
#         if (itp is not None) and (its is not None):
#             for j in range(len(itp[i])):
#                 lb = "P" if j==0 else ""
#                 plt.plot([itp[i][j]*dt, itp[i][j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
#             for j in range(len(its[i])):
#                 lb = "S" if j==0 else ""
#                 plt.plot([its[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
#         if (itps is not None):
#             for j in range(len(itps[i])):
#                 lb = "PS" if j==0 else ""
#                 plt.plot([itps[i][j]*dt, itps[i][j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
#         plt.ylabel('Amplitude')
#         plt.legend(loc='upper right', fontsize='small')
#         plt.gca().set_xticklabels([])
#         plt.text(text_loc[0], text_loc[1], '(ii)', horizontalalignment='center',
#                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        
#         plt.subplot(413)
#         plt.plot(t, data[i, :, 0, 2], 'k', label='Z', linewidth=0.5)
#         plt.autoscale(enable=True, axis='x', tight=True)
#         tmp_min = np.min(data[i, :, 0, 2])
#         tmp_max = np.max(data[i, :, 0, 2])
#         if (itp is not None) and (its is not None):
#             for j in range(len(itp[i])):
#                 lb = "P" if j==0 else ""
#                 plt.plot([itp[i][j]*dt, itp[i][j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
#             for j in range(len(its[i])):
#                 lb = "S" if j==0 else ""
#                 plt.plot([its[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
#         if (itps is not None):
#             for j in range(len(itps[i])):
#                 lb = "PS" if j==0 else ""
#                 plt.plot([itps[i][j]*dt, itps[i][j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
#         plt.ylabel('Amplitude')
#         plt.legend(loc='upper right', fontsize='small')
#         plt.gca().set_xticklabels([])
#         plt.text(text_loc[0], text_loc[1], '(iii)', horizontalalignment='center',
#                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        
#         plt.subplot(414)
#         if label is not None:
#             plt.plot(t, label[i, :, 0, 1], 'C0', label='P', linewidth=1)
#             plt.plot(t, label[i, :, 0, 2], 'C1', label='S', linewidth=1)
#             if label.shape[-1] == 4:
#                 plt.plot(t, label[i, :, 0, 3], 'C2', label='PS', linewidth=1)
#         plt.plot(t, pred[i, :, 0, 1], '--C0', label='$\hat{P}$', linewidth=1)
#         plt.plot(t, pred[i, :, 0, 2], '--C1', label='$\hat{S}$', linewidth=1)
#         if pred.shape[-1] == 4:
#             plt.plot(t, pred[i, :, 0, 3], '--C2', label='$\hat{PS}$', linewidth=1)
#         plt.autoscale(enable=True, axis='x', tight=True)
#         if (itp_pred is not None) and (its_pred is not None) :
#             for j in range(len(itp_pred)):
#                 plt.plot([itp_pred[j]*dt, itp_pred[j]*dt], [-0.1, 1.1], '--C0', linewidth=1)
#             for j in range(len(its_pred)):
#                 plt.plot([its_pred[j]*dt, its_pred[j]*dt], [-0.1, 1.1], '--C1', linewidth=1)
#         if (itps_pred is not None):
#             for j in range(len(itps_pred)):
#                 plt.plot([itps_pred[j]*dt, itps_pred[j]*dt], [-0.1, 1.1], '--C2', linewidth=1)
#         plt.ylim([-0.05, 1.05])
#         plt.text(text_loc[0], text_loc[1], '(iv)', horizontalalignment='center',
#                  transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
#         plt.legend(loc='upper right', fontsize='small', ncol=2)
#         plt.xlabel('Time (s)')
#         plt.ylabel('Probability')
#         plt.tight_layout()
#         plt.gcf().align_labels()

#         try:
#             plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight')
#         except FileNotFoundError:
#             os.makedirs(os.path.dirname(os.path.join(figure_dir, fname[i])), exist_ok=True)
#             plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight')

#         plt.close(i)
#     return 0


def plot_waveform(data, pred, fname, label=None, 
                  itp=None, its=None, itps=None,
                  itp_pred=None, its_pred=None, itps_pred=None,
                  figure_dir="./", dt=0.01):

    t = np.arange(0, pred.shape[0]) * dt
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.05, 0.77]

    plt.figure()
    
    plt.subplot(411)
    plt.plot(t, data[:, 0, 0], 'k', label='E', linewidth=0.5)
    plt.autoscale(enable=True, axis='x', tight=True)
    tmp_min = np.min(data[:, 0, 0])
    tmp_max = np.max(data[:, 0, 0])
    if (itp is not None) and (its is not None):
        for j in range(len(itp)):
            lb = "P" if j==0 else ""
            plt.plot([itp[j]*dt, itp[j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
        for j in range(len(its[i])):
            lb = "S" if j==0 else ""
            plt.plot([its[j]*dt, its[j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
    if (itps is not None):
        for j in range(len(itps)):
            lb = "PS" if j==0 else ""
            plt.plot([itps[j]*dt, its[j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
    plt.ylabel('Amplitude')
    plt.legend(loc='upper right', fontsize='small')
    plt.gca().set_xticklabels([])
    plt.text(text_loc[0], text_loc[1], '(i)', horizontalalignment='center',
                transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    
    plt.subplot(412)
    plt.plot(t, data[:, 0, 1], 'k', label='N', linewidth=0.5)
    plt.autoscale(enable=True, axis='x', tight=True)
    tmp_min = np.min(data[:, 0, 1])
    tmp_max = np.max(data[:, 0, 1])
    if (itp is not None) and (its is not None):
        for j in range(len(itp)):
            lb = "P" if j==0 else ""
            plt.plot([itp[j]*dt, itp[j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
        for j in range(len(its)):
            lb = "S" if j==0 else ""
            plt.plot([its[j]*dt, its[j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
    if (itps is not None):
        for j in range(len(itps)):
            lb = "PS" if j==0 else ""
            plt.plot([itps[j]*dt, itps[j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
    plt.ylabel('Amplitude')
    plt.legend(loc='upper right', fontsize='small')
    plt.gca().set_xticklabels([])
    plt.text(text_loc[0], text_loc[1], '(ii)', horizontalalignment='center',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    
    plt.subplot(413)
    plt.plot(t, data[:, 0, 2], 'k', label='Z', linewidth=0.5)
    plt.autoscale(enable=True, axis='x', tight=True)
    tmp_min = np.min(data[:, 0, 2])
    tmp_max = np.max(data[:, 0, 2])
    if (itp is not None) and (its is not None):
        for j in range(len(itp)):
            lb = "P" if j==0 else ""
            plt.plot([itp[j]*dt, itp[j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5)
        for j in range(len(its)):
            lb = "S" if j==0 else ""
            plt.plot([its[j]*dt, its[j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5)
    if (itps is not None):
        for j in range(len(itps)):
            lb = "PS" if j==0 else ""
            plt.plot([itps[j]*dt, itps[j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5)
    plt.ylabel('Amplitude')
    plt.legend(loc='upper right', fontsize='small')
    plt.gca().set_xticklabels([])
    plt.text(text_loc[0], text_loc[1], '(iii)', horizontalalignment='center',
            transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    
    plt.subplot(414)
    if label is not None:
        plt.plot(t, label[:, 0, 1], 'C0', label='P', linewidth=1)
        plt.plot(t, label[:, 0, 2], 'C1', label='S', linewidth=1)
        if label.shape[-1] == 4:
            plt.plot(t, label[:, 0, 3], 'C2', label='PS', linewidth=1)
    plt.plot(t, pred[:, 0, 1], '--C0', label='$\hat{P}$', linewidth=1)
    plt.plot(t, pred[:, 0, 2], '--C1', label='$\hat{S}$', linewidth=1)
    if pred.shape[-1] == 4:
        plt.plot(t, pred[:, 0, 3], '--C2', label='$\hat{PS}$', linewidth=1)
    plt.autoscale(enable=True, axis='x', tight=True)
    if (itp_pred is not None) and (its_pred is not None) :
        for j in range(len(itp_pred)):
            plt.plot([itp_pred[j]*dt, itp_pred[j]*dt], [-0.1, 1.1], '--C0', linewidth=1)
        for j in range(len(its_pred)):
            plt.plot([its_pred[j]*dt, its_pred[j]*dt], [-0.1, 1.1], '--C1', linewidth=1)
    if (itps_pred is not None):
        for j in range(len(itps_pred)):
            plt.plot([itps_pred[j]*dt, itps_pred[j]*dt], [-0.1, 1.1], '--C2', linewidth=1)
    plt.ylim([-0.05, 1.05])
    plt.text(text_loc[0], text_loc[1], '(iv)', horizontalalignment='center',
                transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
    plt.legend(loc='upper right', fontsize='small', ncol=2)
    plt.xlabel('Time (s)')
    plt.ylabel('Probability')
    plt.tight_layout()
    plt.gcf().align_labels()

    try:
        plt.savefig(os.path.join(figure_dir, fname+'.png'), bbox_inches='tight')
    except FileNotFoundError:
        os.makedirs(os.path.dirname(os.path.join(figure_dir, fname)), exist_ok=True)
        plt.savefig(os.path.join(figure_dir, fname+'.png'), bbox_inches='tight')

    plt.close()
    return 0


def plot_array(config, data, pred, label=None,
               itp=None, its=None, itps=None,
               itp_pred=None, its_pred=None, itps_pred=None,
               fname=None, figure_dir="./", epoch=0):

    dt = config.dt if hasattr(config, "dt") else 1.0
    t = np.arange(0, pred.shape[1]) * dt
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.05, 0.95]
    if fname is None:
        fname = [f"{epoch:03d}_{i:03d}" for i in range(len(data))]
    else:
        fname = [fname[i].decode().rstrip(".npz") for i in range(len(fname))]
        
    for i in range(len(data)):
        plt.figure(i, figsize=(10, 5))
        plt.clf()

        plt.subplot(121)
        for j in range(data.shape[-2]):
            plt.plot(t, data[i, :, j, 0]/10 + j, 'k', label='E', linewidth=0.5)
        plt.autoscale(enable=True, axis='x', tight=True)
        tmp_min = np.min(data[i, :, 0, 0])
        tmp_max = np.max(data[i, :, 0, 0])
        plt.xlabel('Time (s)')
        plt.ylabel('Amplitude')
        # plt.legend(loc='upper right', fontsize='small')
        # plt.gca().set_xticklabels([])
        plt.text(text_loc[0], text_loc[1], '(i)', horizontalalignment='center', verticalalignment="top", 
                 transform=plt.gca().transAxes, fontsize="large", fontweight="normal", bbox=box)
        
        plt.subplot(122)
        for j in range(pred.shape[-2]):
            if label is not None:
                plt.plot(t, label[i, :, j, 1]+j, 'C2', label='P', linewidth=0.5)
                plt.plot(t, label[i, :, j, 2]+j, 'C3', label='S', linewidth=0.5)
                # plt.plot(t, label[i, :, j, 0]+j, 'C4', label='N', linewidth=0.5)
            plt.plot(t, pred[i, :, j, 1]+j, 'C0', label='$\hat{P}$', linewidth=1)
            plt.plot(t, pred[i, :, j, 2]+j, 'C1', label='$\hat{S}$', linewidth=1)
            plt.autoscale(enable=True, axis='x', tight=True)
        if (itp_pred is not None) and (its_pred is not None) and (itps_pred is not None):
            for j in range(len(itp_pred)):
                plt.plot([itp_pred[j]*dt, itp_pred[j]*dt], [-0.1, 1.1], '--C0', linewidth=1)
            for j in range(len(its_pred)):
                plt.plot([its_pred[j]*dt, its_pred[j]*dt], [-0.1, 1.1], '--C1', linewidth=1)
            for j in range(len(itps_pred)):
                plt.plot([itps_pred[j]*dt, itps_pred[j]*dt], [-0.1, 1.1], '--C2', linewidth=1)
        # plt.ylim([-0.05, 1.05])
        plt.text(text_loc[0], text_loc[1], '(ii)', horizontalalignment='center', verticalalignment="top", 
                 transform=plt.gca().transAxes, fontsize="large", fontweight="normal", bbox=box)
        # plt.legend(loc='upper right', fontsize='small', ncol=2)
        plt.xlabel('Time (s)')
        plt.ylabel('Probability')
        plt.tight_layout()
        plt.gcf().align_labels()

        try:
            plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight')
        except FileNotFoundError:
            os.makedirs(os.path.dirname(os.path.join(figure_dir, fname[i])), exist_ok=True)
            plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight')

        plt.close(i)
    return 0


def plot_spectrogram(config, data, pred, label=None, 
                     itp=None, its=None, itps=None,
                     itp_pred=None, its_pred=None, itps_pred=None,
                     time=None, freq=None,
                     fname=None, figure_dir="./", epoch=0):

    # dt = config.dt
    # df = config.df
    # t = np.arange(0, data.shape[1]) * dt
    # f = np.arange(0, data.shape[2]) * df
    t, f = time, freq
    dt = t[1] - t[0]
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.05, 0.75]
    if fname is None:
        fname = [f"{i:03d}" for i in range(len(data))]
    elif type(fname[0]) is bytes:
        fname = [f.decode() for f in fname]
        
    numbers = ["(i)", "(ii)", "(iii)", "(iv)"]
    for i in range(len(data)):
        fig = plt.figure(i)
        # gs = fig.add_gridspec(4, 1)
        
        for j in range(3):
            # fig.add_subplot(gs[j, 0])
            plt.subplot(4,1,j+1)
            plt.pcolormesh(t, f, np.abs(data[i, :, :, j]+1j*data[i, :, :, j+3]).T, vmax=2*np.std(data[i, :, :, j]+1j*data[i, :, :, j+3]), cmap="jet", shading='auto')
            plt.autoscale(enable=True, axis='x', tight=True)
            plt.gca().set_xticklabels([])
            if j == 1:
                plt.ylabel('Frequency (Hz)')
            plt.text(text_loc[0], text_loc[1], numbers[j], horizontalalignment='center',
                    transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)

        # fig.add_subplot(gs[-1, 0])
        plt.subplot(4,1,4)
        if label is not None:
            plt.plot(t, label[i, :, 0, 1], '--C0', linewidth=1)
            plt.plot(t, label[i, :, 0, 2], '--C3', linewidth=1)
            plt.plot(t, label[i, :, 0, 3], '--C1', linewidth=1)
        plt.plot(t, pred[i, :, 0, 1], 'C0', label='P', linewidth=1)
        plt.plot(t, pred[i, :, 0, 2], 'C3', label='S', linewidth=1)
        plt.plot(t, pred[i, :, 0, 3], 'C1', label='PS', linewidth=1)
        plt.plot(t, t*0, 'k', linewidth=1)
        plt.autoscale(enable=True, axis='x', tight=True)
        if (itp_pred is not None) and (its_pred is not None) and (itps_pred is not None):
            for j in range(len(itp_pred)):
                plt.plot([itp_pred[j]*dt, itp_pred[j]*dt], [-0.1, 1.1], ':C3', linewidth=1)
            for j in range(len(its_pred)):
                plt.plot([its_pred[j]*dt, its_pred[j]*dt], [-0.1, 1.1], '-.C6', linewidth=1)
            for j in range(len(itps_pred)):
                plt.plot([itps_pred[j]*dt, itps_pred[j]*dt], [-0.1, 1.1], '--C8', linewidth=1)
        plt.ylim([-0.05, 1.05])
        plt.text(text_loc[0], text_loc[1], numbers[-1], horizontalalignment='center',
                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        plt.legend(loc='upper right', fontsize='small', ncol=1)
        plt.xlabel('Time (s)')
        plt.ylabel('Probability')
        # plt.tight_layout()
        plt.gcf().align_labels()

        try:
            plt.savefig(os.path.join(figure_dir, f'{epoch:02d}_'+fname[i]+'.png'), bbox_inches='tight')
        except FileNotFoundError:
            os.makedirs(os.path.dirname(os.path.join(figure_dir, fname[i])), exist_ok=True)
            plt.savefig(os.path.join(figure_dir, f'{epoch:02d}_'+fname[i]+'.png'), bbox_inches='tight')

        plt.close(i)
    return 0


def plot_spectrogram_waveform(config, spectrogram, waveform, pred, label=None, 
                              itp=None, its=None, itps=None, picks=None,
                              time=None, freq=None,
                              fname=None, figure_dir="./", epoch=0):

    # dt = config.dt
    # df = config.df
    # t = np.arange(0, spectrogram.shape[1]) * dt
    # f = np.arange(0, spectrogram.shape[2]) * df
    t, f = time, freq
    dt = t[1] - t[0]
    box = dict(boxstyle='round', facecolor='white', alpha=1)
    text_loc = [0.02, 0.90]
    if fname is None:
        fname = [f"{i:03d}" for i in range(len(spectrogram))]
    elif type(fname[0]) is bytes:
        fname = [f.decode() for f in fname]
        
    numbers = ["(i)", "(ii)", "(iii)", "(iv)", "(v)", "(vi)", "(vii)"]
    for i in range(len(spectrogram)):
        fig = plt.figure(i, figsize=(6.4, 10))
        # gs = fig.add_gridspec(4, 1)
        
        for j in range(3):
            # fig.add_subplot(gs[j, 0])
            plt.subplot(7,1,j*2+1)
            plt.plot(waveform[i,:,j], 'k', linewidth=0.5)
            plt.autoscale(enable=True, axis='x', tight=True)
            plt.gca().set_xticklabels([])
            plt.ylabel('')
            plt.text(text_loc[0], text_loc[1], numbers[j*2], horizontalalignment='left', verticalalignment='top',
                    transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)

        for j in range(3):
            # fig.add_subplot(gs[j, 0])
            plt.subplot(7,1,j*2+2)
            plt.pcolormesh(t, f, np.abs(spectrogram[i, :, :, j]+1j*spectrogram[i, :, :, j+3]).T, vmax=2*np.std(spectrogram[i, :, :, j]+1j*spectrogram[i, :, :, j+3]), cmap="jet", shading='auto')
            plt.autoscale(enable=True, axis='x', tight=True)
            plt.gca().set_xticklabels([])
            if j == 1:
                plt.ylabel('Frequency (Hz) or Amplitude')
            plt.text(text_loc[0], text_loc[1], numbers[j*2+1], horizontalalignment='left', verticalalignment='top',
                    transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)

        # fig.add_subplot(gs[-1, 0])
        plt.subplot(7,1,7)
        if label is not None:
            plt.plot(t, label[i, :, 0, 1], '--C0', linewidth=1)
            plt.plot(t, label[i, :, 0, 2], '--C3', linewidth=1)
            plt.plot(t, label[i, :, 0, 3], '--C1', linewidth=1)
        plt.plot(t, pred[i, :, 0, 1], 'C0', label='P', linewidth=1)
        plt.plot(t, pred[i, :, 0, 2], 'C3', label='S', linewidth=1)
        plt.plot(t, pred[i, :, 0, 3], 'C1', label='PS', linewidth=1)
        plt.plot(t, t*0, 'k', linewidth=1)
        plt.autoscale(enable=True, axis='x', tight=True)
        plt.ylim([-0.05, 1.05])
        plt.text(text_loc[0], text_loc[1], numbers[-1], horizontalalignment='left', verticalalignment='top',
                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box)
        plt.legend(loc='upper right', fontsize='small', ncol=1)
        plt.xlabel('Time (s)')
        plt.ylabel('Probability')
        # plt.tight_layout()
        plt.gcf().align_labels()

        try:
            plt.savefig(os.path.join(figure_dir, f'{epoch:02d}_'+fname[i]+'.png'), bbox_inches='tight')
        except FileNotFoundError:
            os.makedirs(os.path.dirname(os.path.join(figure_dir, fname[i])), exist_ok=True)
            plt.savefig(os.path.join(figure_dir, f'{epoch:02d}_'+fname[i]+'.png'), bbox_inches='tight')

        plt.close(i)
    return 0
#matplotlib.use("agg") # def plot_waveform(config, data, pred, label=None, #                   itp=None, its=None, itps=None, #                   itp_pred=None, its_pred=None, itps_pred=None, #                   fname=None, figure_dir="./", epoch=0, max_fig=10): #     dt = config.dt if hasattr(config, "dt") else 1.0 #     t = np.arange(0, pred.shape[1]) * dt #     box = dict(boxstyle='round', facecolor='white', alpha=1) #     text_loc = [0.05, 0.77] #     if fname is None: #         fname = [f"{epoch:03d}_{i:02d}" for i in range(len(data))] #     else: #         fname = [fname[i].decode().rstrip(".npz") for i in range(len(fname))] #     for i in range(min(len(data), max_fig)): #         plt.figure(i) #         plt.subplot(411) #         plt.plot(t, data[i, :, 0, 0], 'k', label='E', linewidth=0.5) #         plt.autoscale(enable=True, axis='x', tight=True) #         tmp_min = np.min(data[i, :, 0, 0]) #         tmp_max = np.max(data[i, :, 0, 0]) #         if (itp is not None) and (its is not None): #             for j in range(len(itp[i])): #                 lb = "P" if j==0 else "" #                 plt.plot([itp[i][j]*dt, itp[i][j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5) #             for j in range(len(its[i])): #                 lb = "S" if j==0 else "" #                 plt.plot([its[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5) #         if (itps is not None): #             for j in range(len(itps[i])): #                 lb = "PS" if j==0 else "" #                 plt.plot([itps[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5) #         plt.ylabel('Amplitude') #         plt.legend(loc='upper right', fontsize='small') #         plt.gca().set_xticklabels([]) #         plt.text(text_loc[0], text_loc[1], '(i)', horizontalalignment='center', #                  transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box) #         plt.subplot(412) #         plt.plot(t, data[i, :, 0, 1], 'k', label='N', linewidth=0.5) #         plt.autoscale(enable=True, axis='x', tight=True) #         tmp_min = np.min(data[i, :, 0, 1]) #         tmp_max = np.max(data[i, :, 0, 1]) #         if (itp is not None) and (its is not None): #             for j in range(len(itp[i])): #                 lb = "P" if j==0 else "" #                 plt.plot([itp[i][j]*dt, itp[i][j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5) #             for j in range(len(its[i])): #                 lb = "S" if j==0 else "" #                 plt.plot([its[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5) #         if (itps is not None): #             for j in range(len(itps[i])): #                 lb = "PS" if j==0 else "" #                 plt.plot([itps[i][j]*dt, itps[i][j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5) #         plt.ylabel('Amplitude') #         plt.legend(loc='upper right', fontsize='small') #         plt.gca().set_xticklabels([]) #         plt.text(text_loc[0], text_loc[1], '(ii)', horizontalalignment='center', #                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box) #         plt.subplot(413) #         plt.plot(t, data[i, :, 0, 2], 'k', label='Z', linewidth=0.5) #         plt.autoscale(enable=True, axis='x', tight=True) #         tmp_min = np.min(data[i, :, 0, 2]) #         tmp_max = np.max(data[i, :, 0, 2]) #         if (itp is not None) and (its is not None): #             for j in range(len(itp[i])): #                 lb = "P" if j==0 else "" #                 plt.plot([itp[i][j]*dt, itp[i][j]*dt], [tmp_min, tmp_max], 'C0', label=lb, linewidth=0.5) #             for j in range(len(its[i])): #                 lb = "S" if j==0 else "" #                 plt.plot([its[i][j]*dt, its[i][j]*dt], [tmp_min, tmp_max], 'C1', label=lb, linewidth=0.5) #         if (itps is not None): #             for j in range(len(itps[i])): #                 lb = "PS" if j==0 else "" #                 plt.plot([itps[i][j]*dt, itps[i][j]*dt], [tmp_min, tmp_max], 'C2', label=lb, linewidth=0.5) #         plt.ylabel('Amplitude') #         plt.legend(loc='upper right', fontsize='small') #         plt.gca().set_xticklabels([]) #         plt.text(text_loc[0], text_loc[1], '(iii)', horizontalalignment='center', #                 transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box) #         plt.subplot(414) #         if label is not None: #             plt.plot(t, label[i, :, 0, 1], 'C0', label='P', linewidth=1) #             plt.plot(t, label[i, :, 0, 2], 'C1', label='S', linewidth=1) #             if label.shape[-1] == 4: #                 plt.plot(t, label[i, :, 0, 3], 'C2', label='PS', linewidth=1) #         plt.plot(t, pred[i, :, 0, 1], '--C0', label='$\hat{P}$', linewidth=1) #         plt.plot(t, pred[i, :, 0, 2], '--C1', label='$\hat{S}$', linewidth=1) #         if pred.shape[-1] == 4: #             plt.plot(t, pred[i, :, 0, 3], '--C2', label='$\hat{PS}$', linewidth=1) #         plt.autoscale(enable=True, axis='x', tight=True) #         if (itp_pred is not None) and (its_pred is not None) : #             for j in range(len(itp_pred)): #                 plt.plot([itp_pred[j]*dt, itp_pred[j]*dt], [-0.1, 1.1], '--C0', linewidth=1) #             for j in range(len(its_pred)): #                 plt.plot([its_pred[j]*dt, its_pred[j]*dt], [-0.1, 1.1], '--C1', linewidth=1) #         if (itps_pred is not None): #             for j in range(len(itps_pred)): #                 plt.plot([itps_pred[j]*dt, itps_pred[j]*dt], [-0.1, 1.1], '--C2', linewidth=1) #         plt.ylim([-0.05, 1.05]) #         plt.text(text_loc[0], text_loc[1], '(iv)', horizontalalignment='center', #                  transform=plt.gca().transAxes, fontsize="small", fontweight="normal", bbox=box) #         plt.legend(loc='upper right', fontsize='small', ncol=2) #         plt.xlabel('Time (s)') #         plt.ylabel('Probability') #         plt.tight_layout() #         plt.gcf().align_labels() #         try: #             plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight') #         except FileNotFoundError: #             os.makedirs(os.path.dirname(os.path.join(figure_dir, fname[i])), exist_ok=True) #             plt.savefig(os.path.join(figure_dir, fname[i]+'.png'), bbox_inches='tight') #         plt.close(i) #     return 0 # plt.legend(loc='upper right', fontsize='small') # plt.gca().set_xticklabels([]) # plt.plot(t, label[i, :, j, 0]+j, 'C4', label='N', linewidth=0.5) # plt.ylim([-0.05, 1.05]) # plt.legend(loc='upper right', fontsize='small', ncol=2) # dt = config.dt # df = config.df # t = np.arange(0, data.shape[1]) * dt # f = np.arange(0, data.shape[2]) * df # gs = fig.add_gridspec(4, 1) # fig.add_subplot(gs[j, 0]) # fig.add_subplot(gs[-1, 0]) # plt.tight_layout() # dt = config.dt # df = config.df # t = np.arange(0, spectrogram.shape[1]) * dt # f = np.arange(0, spectrogram.shape[2]) * df # gs = fig.add_gridspec(4, 1) # fig.add_subplot(gs[j, 0]) # fig.add_subplot(gs[j, 0]) # fig.add_subplot(gs[-1, 0]) # plt.tight_layout()