jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def plot_sml_morethan1tissues(df, y=50):
    '''Plot bars countig the number of variants that are present in each sml
    region and that are not only found in 1 tissue.'''
    
    df = df[(~(df.SET_ONE_TISSUE)) & (df.IN_25 == True) &
            (df.LG_SM == 'Sml')].sort_values(by=['ORGAN_SORTER', 'L_R'])
    
    sns.countplot(x='BRAIN_REGION', hue='L_R', data=df,
                  order=['PF', 'F', 'P', 'O', 'T'], edgecolor='k')
    
    plt.ylim(0, y)
    plt.ylabel('Number of Variants')
    plt.xlabel('Cortical Lobes')
    sns.utils.despine(bottom=True, offset=5, trim=True)
    
    plt.show()
//  [python]
def plot_sml_1tissues(df, y=50):
    '''Plot bars counting the number of variants that are only present in one
    small region.'''
    
    df = df[(df.MAX_MAF_25_BOOL) & (df.SET_CORTEX_ONLY) & (df.SET_ONE_TISSUE) &
            (df.LG_SM == 'Sml')].sort_values(by=['ORGAN_SORTER', 'L_R'])
    
    #to fix the issue with 0bars
    fake = pd.DataFrame(data={'BRAIN_REGION': ['F', 'O'],
                              'L_R': ['R', 'L']})
    
    df = df.append(fake, sort=False).reset_index(drop=True)
    
    sns.countplot(x='BRAIN_REGION', hue='L_R', data=df,
                  order=['PF', 'F', 'P', 'O', 'T'], edgecolor='k')
    
    plt.axhline(y=5.3, color='r')
    plt.axhline(y=10.6, color='r')
    plt.axhline(y=18.3, color='r')
    
    plt.ylim(0, y)
    plt.ylabel('Number of Variants')
    plt.xlabel('Cortical Lobes')
    plt.title('Remove R-F and L-O!')
    sns.despine(bottom=True, offset=5, trim=True)
    
    plt.show()
//  [python]
def plot_sml_1tissues(df, y=50):
    '''Plot bars counting the number of variants that are only present in one
    small region.'''
    
    df = df[(df.MAX_MAF_25_BOOL) & (df.SET_CORTEX_ONLY) & (df.SET_ONE_TISSUE) &
            (df.LG_SM == 'Sml')].sort_values(by=['ORGAN_SORTER', 'L_R'])
    
    #to fix the issue with 0bars
    fake = pd.DataFrame(data={'BRAIN_REGION': ['F', 'O'],
                              'L_R': ['R', 'L']})
    
    df = df.append(fake, sort=False).reset_index(drop=True)
    
    sns.countplot(x='BRAIN_REGION', hue='L_R', data=df,
                  order=['PF', 'F', 'P', 'O', 'T'], edgecolor='k')
    
    plt.axhline(y=5.3, color='r')
    plt.axhline(y=10.6, color='r')
    plt.axhline(y=18.3, color='r')
    
    plt.ylim(0, y)
    plt.ylabel('Number of Variants')
    plt.xlabel('Cortical Lobes')
    plt.title('Remove R-F and L-O!')
    sns.utils.despine(bottom=True, offset=5, trim=True)
    
    plt.show()
//  [python]
def plot_welch_periodogram(self, data,  sf=256, win_size = 4, log_power = False):
        
        """
        Plot the welch periodogram
        
        :param self: access the attributes and methods of the class
        :param data: EEG data
        :param sf: sampoling frequency 
        :param win_size: the size of sliding windows for Welch method.
        :param log_power: compute logarithmic power
        
        :returns: plot
        
        """
        
        from scipy import signal
        import seaborn as sns
        import yasa
        
        # Define window length (4 seconds)
        win = win_size * sf
        freqs, psd = signal.welch(data, sf, nperseg=win)
        
        if log_power:
            psd = 20 * np.log10(psd)
        
        # Compute vvalues: 
        ret = yasa.bandpower(data, sf=sf)
        # Plot the power spectrum
        sns.set(font_scale=1.2, style='white')
        plt.figure(figsize=(8, 4))
        plt.plot(freqs, psd, color='k', lw=2)
        plt.xlabel('Frequency (Hz)')
        plt.ylabel('Power spectral density (V^2 / Hz)')
        plt.ylim([0, psd.max() * 1.1])
        plt.title("Welch's periodogram")
        plt.xlim([0, 30])
        sns.despine()
        
        
        # Delta
        plt.axvline(.5, linestyle='--', color='black')
        plt.axvline(4, linestyle='--', color='black')
    
        # Theta
        plt.axvline(8, linestyle='--', color='black')
    
        # Alpha
        plt.axvline(12, linestyle='--', color='black')
        
        loc_pow_vals = np.mean([np.min(psd), np.max(psd)])
        loc_labels = loc_pow_vals
        plt.text(1.3, loc_labels, 'Delta', size=8)
        plt.text(4.8, loc_labels, 'Theta', size=8)
        plt.text(8.8, loc_labels, 'Alpha', size=8)
        plt.text(12.8, loc_labels, 'Beta', size=8)
    
        # legend - values
        plt.legend([f'Delta (0.5-4 Hz)): {round(ret["Delta"][0] * 100, 2)}% \n\
    Theta (4-8 Hz): {round(ret["Theta"][0] * 100, 2)}% \n\
    Alpha (8-12 Hz): {round(ret["Alpha"][0] * 100, 2)}% \n\
    Sigma (12-16 Hz): {round(ret["Sigma"][0] * 100, 2)}% \n\
    Beta (16-30 Hz): {round(ret["Beta"][0] * 100, 2)}% \n\
    Gamma (30-40 Hz): {round(ret["Gamma"][0] * 100, 2)}%'], prop={'size': 10}, frameon=False)
//  [python]
def plot_welch_periodogram(self, data,  sf=256, win_size = 4, log_power = False):
        
        """
        Plot the welch periodogram
        
        :param self: access the attributes and methods of the class
        :param data: EEG data
        :param sf: sampoling frequency 
        :param win_size: the size of sliding windows for Welch method.
        :param log_power: compute logarithmic power
        
        :returns: plot
        
        """
        
        from scipy import signal
        import seaborn as sns
        import yasa
        import matplotlib.pyplot as plt
        import numpy as np
        
        # Define window length (4 seconds)
        win = win_size * sf
        freqs, psd = signal.welch(data, sf, nperseg=win)
        
        if log_power:
            psd = 20 * np.log10(psd)
        
        # Compute vvalues: 
        ret = yasa.bandpower(data, sf=sf)
        # Plot the power spectrum
        sns.set(font_scale=1.2, style='white')
        plt.figure(figsize=(8, 4))
        plt.plot(freqs, psd, color='k', lw=2)
        plt.xlabel('Frequency (Hz)')
        plt.ylabel('Power spectral density (V^2 / Hz)')
        plt.ylim([0, psd.max() * 1.1])
        plt.title("Welch's periodogram")
        plt.xlim([0, 30])
        sns.utils.despine()
        
        
        # Delta
        plt.axvline(.5, linestyle='--', color='black')
        plt.axvline(4, linestyle='--', color='black')
    
        # Theta
        plt.axvline(8, linestyle='--', color='black')
    
        # Alpha
        plt.axvline(12, linestyle='--', color='black')
        
        loc_pow_vals = np.mean([np.min(psd), np.max(psd)])
        loc_labels = loc_pow_vals
        plt.text(1.3, loc_labels, 'Delta', size=8)
        plt.text(4.8, loc_labels, 'Theta', size=8)
        plt.text(8.8, loc_labels, 'Alpha', size=8)
        plt.text(12.8, loc_labels, 'Beta', size=8)
    
        # legend - values
        plt.legend([f'Delta (0.5-4 Hz)): {round(ret["Delta"][0] * 100, 2)}% \n\
    Theta (4-8 Hz): {round(ret["Theta"][0] * 100, 2)}% \n\
    Alpha (8-12 Hz): {round(ret["Alpha"][0] * 100, 2)}% \n\
    Sigma (12-16 Hz): {round(ret["Sigma"][0] * 100, 2)}% \n\
    Beta (16-30 Hz): {round(ret["Beta"][0] * 100, 2)}% \n\
    Gamma (30-40 Hz): {round(ret["Gamma"][0] * 100, 2)}%'], prop={'size': 10}, frameon=False)
//  [python]
def plot_cases_deaths(df: pd.DataFrame, target_location: str) -> None:
    st.markdown(f"# Numéro de Casos and Mortos - {target_location}")
    df[["total_cases", "total_deaths"]].plot()
    sns.despine()
    plt.grid()
    plt.title(f"Cases and Deaths - {target_location}")
    st.pyplot()
//  [python]
def plot_cases_deaths(df: pd.DataFrame, target_location: str) -> None:
    st.markdown(f"# Numéro de Casos and Mortos - {target_location}")
    df[["total_cases", "total_deaths"]].plot()
    sns.utils.despine()
    plt.grid()
    plt.title(f"Cases and Deaths - {target_location}")
    st.pyplot()
//  [python]
def plot_number25_vsAF(df):
    '''note that OR lines are drawn at 5.5 and 0.05 manually)'''
    
    df = df.copy()
    
    df.fillna(0, inplace=True)
    
    df = df[(df.EXPERIMENT == 'bulk') & (df.CONSIDERED_MAF_25 != 0)]
    
    df['MAF_'] = df.CONSIDERED_MAF_25**0.5
    
    sns.regplot(x='MAF_', y='SUM_POS_25', data=df, color='k',
                scatter_kws={'s':4, 'alpha':0.1}, fit_reg=False)
                #, line_kws={'color':'r'})
    #sns.jointplot('MAF_', 'SUM_POS_25', kind='kde', data=df,
     #             color='r')#.plot_joint(sns.regplot, marker='o', color='k')
    
    plt.xlabel('Allelic Fraction (sqrt-t)')
    plt.xlim(0, 1)
    plt.xticks(ticks=[0., 0.01**0.5, 0.05**0.5, 0.1**0.5, 0.2**0.5, 0.5**0.5],
               labels=['0.00', '0.01', '0.05', '0.10', '0.20', '0.50'])
    
    plt.ylabel('Number of Samples')
    plt.ylim(0, 25)
    plt.xlim(0, 1)
    plt.yticks(ticks=[0, 5, 10, 15, 20, 25])
    
    sns.despine(offset=5, trim=True)
    
    plt.show()
//  [python]
def plot_number25_vsAF(df):
    '''note that OR lines are drawn at 5.5 and 0.05 manually)'''
    
    df = df.copy()
    
    df.fillna(0, inplace=True)
    
    df = df[(df.EXPERIMENT == 'bulk') & (df.CONSIDERED_MAF_25 != 0)]
    
    df['MAF_'] = df.CONSIDERED_MAF_25**0.5
    
    sns.regplot(x='MAF_', y='SUM_POS_25', data=df, color='k',
                scatter_kws={'s':4, 'alpha':0.1}, fit_reg=False)
                #, line_kws={'color':'r'})
    #sns.jointplot('MAF_', 'SUM_POS_25', kind='kde', data=df,
     #             color='r')#.plot_joint(sns.regplot, marker='o', color='k')
    
    plt.xlabel('Allelic Fraction (sqrt-t)')
    plt.xlim(0, 1)
    plt.xticks(ticks=[0., 0.01**0.5, 0.05**0.5, 0.1**0.5, 0.2**0.5, 0.5**0.5],
               labels=['0.00', '0.01', '0.05', '0.10', '0.20', '0.50'])
    
    plt.ylabel('Number of Samples')
    plt.ylim(0, 25)
    plt.xlim(0, 1)
    plt.yticks(ticks=[0, 5, 10, 15, 20, 25])
    
    sns.utils.despine(offset=5, trim=True)
    
    plt.show()
//  [python]
def make_AF_plot_variant_onax(df, POS, ax, depth=100):
    '''take the position and plot AF in all tissues for this position in boxes
    that are graded by AF level.'''
    
    #initialize data
    
        
    pos = df[(df.POS == POS) & (df.EXPERIMENT == 'bulk')][['CHR_POS_REF_ALT',
                                                           'MAF', 'SORTER',
                                                           'DEPTH',
                                                           'FLAG_NOISE']]
    pos.sort_values(by='SORTER', inplace=True)
    
    #make color list/hatches
    colors = make_colors(pos)
    hatches = make_hatches(pos, depth)
    
    #make boxes
    boxes = make_boxes()
    
    for box, color, hatch in zip(boxes, colors, hatches):
        box.set_facecolor(color)
        box.set_edgecolor('k')
        box.set_hatch(hatch)
        ax.add_patch(box)
        
    ax.plot()
    sns.despine(left=True, bottom=True)
    ax.set_xlim(-14.75, 35.25)
    ax.set_ylim(0, 50)
    
    ax.set_title(pos.CHR_POS_REF_ALT.unique()[0], fontsize=6) #fontsize=6

    return ax
//  [python]
def make_AF_plot_variant_onax(df, POS, ax, depth=100):
    '''take the position and plot AF in all tissues for this position in boxes
    that are graded by AF level.'''
    
    #initialize data
    
        
    pos = df[(df.POS == POS) & (df.EXPERIMENT == 'bulk')][['CHR_POS_REF_ALT',
                                                           'MAF', 'SORTER',
                                                           'DEPTH',
                                                           'FLAG_NOISE']]
    pos.sort_values(by='SORTER', inplace=True)
    
    #make color list/hatches
    colors = make_colors(pos)
    hatches = make_hatches(pos, depth)
    
    #make boxes
    boxes = make_boxes()
    
    for box, color, hatch in zip(boxes, colors, hatches):
        box.set_facecolor(color)
        box.set_edgecolor('k')
        box.set_hatch(hatch)
        ax.add_patch(box)
        
    ax.plot()
    sns.utils.despine(left=True, bottom=True)
    ax.set_xlim(-14.75, 35.25)
    ax.set_ylim(0, 50)
    
    ax.set_title(pos.CHR_POS_REF_ALT.unique()[0], fontsize=6) #fontsize=6

    return ax
//  [python]
def make_AF_plot_variant(df, POS, depth=100, return_flag=False):
    '''take the position and plot AF in all tissues for this position in boxes
    that are graded by AF level.'''
    
    #initialize data
    pos = df[(df.POS == POS) & (df.EXPERIMENT == 'bulk')][['CHR_POS_REF_ALT',
                                                           'MAF', 'SORTER',
                                                           'DEPTH',
                                                           'FLAG_NOISE']]
    pos.sort_values(by='SORTER', inplace=True)
    
    #make color list/hatches
    colors = make_colors(pos)
    hatches = make_hatches(pos, depth)
    
    #make boxes
    fig, ax = plt.subplots(1)

    boxes = make_boxes()
    
    for box, color, hatch in zip(boxes, colors, hatches):
        box.set_facecolor(color)
        box.set_edgecolor('k')
        box.set_hatch(hatch)
        ax.add_patch(box)
        
    ax.plot()
    sns.despine(left=True, bottom=True)
    plt.tick_params(bottom=False, left=False,
                    labelbottom=False, labelleft=False)
    plt.xlim(-14.75, 35.25)
    plt.ylim(0, 50)
    
    plt.title(pos.CHR_POS_REF_ALT.unique()[0])

    if return_flag == True:
        return ax
    
    else:
        plt.show()
//  [python]
def make_AF_plot_variant(df, POS, depth=100, return_flag=False):
    '''take the position and plot AF in all tissues for this position in boxes
    that are graded by AF level.'''
    
    #initialize data
    pos = df[(df.POS == POS) & (df.EXPERIMENT == 'bulk')][['CHR_POS_REF_ALT',
                                                           'MAF', 'SORTER',
                                                           'DEPTH',
                                                           'FLAG_NOISE']]
    pos.sort_values(by='SORTER', inplace=True)
    
    #make color list/hatches
    colors = make_colors(pos)
    hatches = make_hatches(pos, depth)
    
    #make boxes
    fig, ax = plt.subplots(1)

    boxes = make_boxes()
    
    for box, color, hatch in zip(boxes, colors, hatches):
        box.set_facecolor(color)
        box.set_edgecolor('k')
        box.set_hatch(hatch)
        ax.add_patch(box)
        
    ax.plot()
    sns.utils.despine(left=True, bottom=True)
    plt.tick_params(bottom=False, left=False,
                    labelbottom=False, labelleft=False)
    plt.xlim(-14.75, 35.25)
    plt.ylim(0, 50)
    
    plt.title(pos.CHR_POS_REF_ALT.unique()[0])

    if return_flag == True:
        return ax
    
    else:
        plt.show()
//  [python]
def make_abspres_plot(df, POS, brain_only=False):
    '''just use the IN_25 to make a presence/absence plot for the entire phage
    or just the brain regions dependin on flag brain_only.'''
    
    #initialize df
    df = df[(df.EXPERIMENT == 'bulk') & (df.POS == POS)]
    sorter(df)
    
    #make color list
    colors = ['xkcd:pale pink' if in25 == 1 else '0.9' for in25 in df.IN_25]
    
    #make boxes
    fig,ax = plt.subplots(1)

    boxes = make_boxes_abspres(brain_only)
        
    pc = PatchCollection(boxes, facecolor=colors, edgecolor='w')
    ax.add_collection(pc)
    
    ax.plot()
    ax.set(adjustable='box', aspect='equal')
    sns.despine(left=True, bottom=True)
    plt.tick_params(bottom=False, left=False,
                    labelbottom=False, labelleft=False)
    plt.xlim(0,20)
    plt.ylim(-1, 59)
    
    plt.title(df.CHR_POS_REF_ALT.unique()[0])

    plt.show()
//  [python]
def make_abspres_plot(df, POS, brain_only=False):
    '''just use the IN_25 to make a presence/absence plot for the entire phage
    or just the brain regions dependin on flag brain_only.'''
    
    #initialize df
    df = df[(df.EXPERIMENT == 'bulk') & (df.POS == POS)]
    sorter(df)
    
    #make color list
    colors = ['xkcd:pale pink' if in25 == 1 else '0.9' for in25 in df.IN_25]
    
    #make boxes
    fig,ax = plt.subplots(1)

    boxes = make_boxes_abspres(brain_only)
        
    pc = PatchCollection(boxes, facecolor=colors, edgecolor='w')
    ax.add_collection(pc)
    
    ax.plot()
    ax.set(adjustable='box', aspect='equal')
    sns.utils.despine(left=True, bottom=True)
    plt.tick_params(bottom=False, left=False,
                    labelbottom=False, labelleft=False)
    plt.xlim(0,20)
    plt.ylim(-1, 59)
    
    plt.title(df.CHR_POS_REF_ALT.unique()[0])

    plt.show()
//  [python]
def plot_overlap_ms2rescore_prosit(ms2rescore_psms, prosit_psms, label1='MS2ReScore', label2='Prosit'):
    
    fig = plt.figure(figsize=[2,10])
    ax = fig.add_subplot(1,1,1)
    
    overlap = len(set(ms2rescore_psms).intersection(set(prosit_psms)))
    ms2rescore_len = len(ms2rescore_psms)-overlap
    prosit_len = len(prosit_psms)-overlap
    
    rects = ax.bar(0, ms2rescore_len)
    rects2 = ax.bar(1, overlap)
    rects3 = ax.bar(2, prosit_len)
    
    plt.xticks([0,1,2], [label1, 'Overlap',label2],
               rotation=90)
    
    plt.grid(axis='x')
    plt.tight_layout()
    sns.despine(right=True, left=True, bottom=False)
    
    plt.show()
    
    return
//  [python]
def plot_overlap_ms2rescore_prosit(ms2rescore_psms, prosit_psms, label1='MS2ReScore', label2='Prosit'):
    
    fig = plt.figure(figsize=[2,10])
    ax = fig.add_subplot(1,1,1)
    
    overlap = len(set(ms2rescore_psms).intersection(set(prosit_psms)))
    ms2rescore_len = len(ms2rescore_psms)-overlap
    prosit_len = len(prosit_psms)-overlap
    
    rects = ax.bar(0, ms2rescore_len)
    rects2 = ax.bar(1, overlap)
    rects3 = ax.bar(2, prosit_len)
    
    plt.xticks([0,1,2], [label1, 'Overlap',label2],
               rotation=90)
    
    plt.grid(axis='x')
    plt.tight_layout()
    sns.utils.despine(right=True, left=True, bottom=False)
    
    plt.show()
    
    return
//  [python]
def loliplot_NeuN_TBR1_onax(df, POS, ax, side, brreg):
    
    '''plot NeuN and TBR1 in a small loliplot but onax.'''
    
    markers = ['NeuN', 'TBR1']
    
    df = df[(df.EXPERIMENT.isin(markers)) & (df.POS == POS) &
            (df.L_R == side) & (df.BRAIN_REGION == brreg)]
    sorter(df)
    
    colors = make_loli_NT_colors(df)
    
    df['MAF_'] = (df.CONSIDERED_MAF_TISSUE * df.SET_SORT_INCLUDED)**0.5
    
    maxi, semi, maxi_l, semi_l = get_ticks(df)
    
    for i in range(2):
    
        ax.vlines([0 + i/4], ymin=[0],
                   ymax=df[df.EXPERIMENT == markers[i]].MAF_)
        ax.scatter([0 + i/4], df[df.EXPERIMENT == markers[i]].MAF_,
                    color=[colors[i]], s=100, edgecolors='k', zorder=100)
    
    ax.set_xlim(-0.1, .35)
    ax.set_ylim(-((maxi/1000)**0.5), maxi**0.5)
    
    ax.set_xticks([0.125])
    ax.set_xticklabels(['NeuN/TBR1'])
    ax.set_yticks([0., semi**0.5, maxi**0.5])
    ax.set_yticklabels(['0.0', semi_l, maxi_l])
    
    ax.set_xlabel('')
    ax.set_ylabel('AF (sqrt-t)')
    
    sns.despine(bottom=True, trim=True, offset=5, ax=ax)
    
    ax.set(adjustable='box', aspect=15)
    
    return ax
//  [python]
def loliplot_NeuN_TBR1_onax(df, POS, ax, side, brreg):
    
    '''plot NeuN and TBR1 in a small loliplot but onax.'''
    
    markers = ['NeuN', 'TBR1']
    
    df = df[(df.EXPERIMENT.isin(markers)) & (df.POS == POS) &
            (df.L_R == side) & (df.BRAIN_REGION == brreg)]
    sorter(df)
    
    colors = make_loli_NT_colors(df)
    
    df['MAF_'] = (df.CONSIDERED_MAF_TISSUE * df.SET_SORT_INCLUDED)**0.5
    
    maxi, semi, maxi_l, semi_l = get_ticks(df)
    
    for i in range(2):
    
        ax.vlines([0 + i/4], ymin=[0],
                   ymax=df[df.EXPERIMENT == markers[i]].MAF_)
        ax.scatter([0 + i/4], df[df.EXPERIMENT == markers[i]].MAF_,
                    color=[colors[i]], s=100, edgecolors='k', zorder=100)
    
    ax.set_xlim(-0.1, .35)
    ax.set_ylim(-((maxi/1000)**0.5), maxi**0.5)
    
    ax.set_xticks([0.125])
    ax.set_xticklabels(['NeuN/TBR1'])
    ax.set_yticks([0., semi**0.5, maxi**0.5])
    ax.set_yticklabels(['0.0', semi_l, maxi_l])
    
    ax.set_xlabel('')
    ax.set_ylabel('AF (sqrt-t)')
    
    sns.utils.despine(bottom=True, trim=True, offset=5, ax=ax)
    
    ax.set(adjustable='box', aspect=15)
    
    return ax
//  [python]
def loliplot_NeuN_TBR1_Dlx1_onax(df, POS, ax, side, brreg):
    
    '''plot NeuN and TBR1 in a small loliplot but onax.'''
    
    markers = ['NeuN', 'TBR1', 'Dlx1']
    
    df = df[(df.EXPERIMENT.isin(markers)) & (df.POS == POS) &
            (df.L_R == side) & (df.BRAIN_REGION == brreg)]
    sorter(df)
    
    colors = make_loli_NTD_colors(df)
    
    df['MAF_'] = (df.CONSIDERED_MAF_TISSUE * df.SET_SORT_INCLUDED)**0.5
    
    maxi, semi, maxi_l, semi_l = get_ticks(df)
    
    for i in range(3):
    
        ax.vlines([0 + i/3], ymin=[0],
                   ymax=df[df.EXPERIMENT == markers[i]].MAF_)
        ax.scatter([0 + i/3], df[df.EXPERIMENT == markers[i]].MAF_,
                    color=[colors[i]], s=100, edgecolors='k', zorder=100)
    
    ax.set_xlim(-0.1, .85)
    ax.set_ylim(-((maxi/1000)**0.5), maxi**0.5)
    
    ax.set_xticks([0.375])
    ax.set_xticklabels(['NeuN/TBR1/DLX1'])
    ax.set_yticks([0., semi**0.5, maxi**0.5])
    ax.set_yticklabels(['0.0', semi_l, maxi_l])
    
    ax.set_xlabel('')
    ax.set_ylabel('')
    
    sns.despine(bottom=True, trim=True, offset=5, ax=ax)
    
    ax.set(adjustable='box', aspect=15)
    
    return ax
//  [python]
def loliplot_NeuN_TBR1_Dlx1_onax(df, POS, ax, side, brreg):
    
    '''plot NeuN and TBR1 in a small loliplot but onax.'''
    
    markers = ['NeuN', 'TBR1', 'Dlx1']
    
    df = df[(df.EXPERIMENT.isin(markers)) & (df.POS == POS) &
            (df.L_R == side) & (df.BRAIN_REGION == brreg)]
    sorter(df)
    
    colors = make_loli_NTD_colors(df)
    
    df['MAF_'] = (df.CONSIDERED_MAF_TISSUE * df.SET_SORT_INCLUDED)**0.5
    
    maxi, semi, maxi_l, semi_l = get_ticks(df)
    
    for i in range(3):
    
        ax.vlines([0 + i/3], ymin=[0],
                   ymax=df[df.EXPERIMENT == markers[i]].MAF_)
        ax.scatter([0 + i/3], df[df.EXPERIMENT == markers[i]].MAF_,
                    color=[colors[i]], s=100, edgecolors='k', zorder=100)
    
    ax.set_xlim(-0.1, .85)
    ax.set_ylim(-((maxi/1000)**0.5), maxi**0.5)
    
    ax.set_xticks([0.375])
    ax.set_xticklabels(['NeuN/TBR1/DLX1'])
    ax.set_yticks([0., semi**0.5, maxi**0.5])
    ax.set_yticklabels(['0.0', semi_l, maxi_l])
    
    ax.set_xlabel('')
    ax.set_ylabel('')
    
    sns.utils.despine(bottom=True, trim=True, offset=5, ax=ax)
    
    ax.set(adjustable='box', aspect=15)
    
    return ax
//  [python]
def start_plotting(fig_size, fig_pos, style="ticks", rc=None, despine=False):
    with sns.axes_style(style, rc):
        fig = plt.figure(figsize=fig_size)
        if not fig_pos:
            ax = fig.add_subplot(111)
        else:
            ax = fig.add_axes(fig_pos)
    if despine:
        sns.despine(left=True)
    return fig, ax
//  [python]
def start_plotting(fig_size, fig_pos, style="ticks", rc=None, despine=False):
    with sns.axes_style(style, rc):
        fig = plt.figure(figsize=fig_size)
        if not fig_pos:
            ax = fig.add_subplot(111)
        else:
            ax = fig.add_axes(fig_pos)
    if despine:
        sns.utils.despine(left=True)
    return fig, ax
//  [python]
def plot_per_file_identity_curve(identities_per_file, title=None, output_base=None):
    name_key_start=8
    name_key_end=19
    basename = True

    identities_per_file = merge_dicts_by_key_idx(identities_per_file, key_start_pos=name_key_start,
                                                 key_end_pos=name_key_end, basename=basename)

    # how to order these
    ordered_keys = list(identities_per_file.keys())
    ordered_keys.sort()

    # print mmm
    for key in ordered_keys:
        mmm(identities_per_file[key], identifier=key)

    sns.set(style="white", palette="bright", color_codes=True)
    for key in ordered_keys:
        sns.distplot(identities_per_file[key], hist=False, rug=False, kde_kws={"shade": True, "linewidth": 1},
                     color='grey' if 'n' in key else 'blue')
    sns.despine(left=True, top=True, right=True)
    pyplot.yticks([])
    pyplot.xlim([.5, 1])


    if output_base is not None:
        pyplot.savefig("{}.identity_comparison_curve.png".format(output_base))
    pyplot.show()
    pyplot.close()
//  [python]
def plot_per_file_identity_curve(identities_per_file, title=None, output_base=None):
    name_key_start=8
    name_key_end=19
    basename = True

    identities_per_file = merge_dicts_by_key_idx(identities_per_file, key_start_pos=name_key_start,
                                                 key_end_pos=name_key_end, basename=basename)

    # how to order these
    ordered_keys = list(identities_per_file.keys())
    ordered_keys.sort()

    # print mmm
    for key in ordered_keys:
        mmm(identities_per_file[key], identifier=key)

    sns.set(style="white", palette="bright", color_codes=True)
    for key in ordered_keys:
        sns.distplot(identities_per_file[key], hist=False, rug=False, kde_kws={"shade": True, "linewidth": 1},
                     color='grey' if 'n' in key else 'blue')
    sns.utils.despine(left=True, top=True, right=True)
    pyplot.yticks([])
    pyplot.xlim([.5, 1])


    if output_base is not None:
        pyplot.savefig("{}.identity_comparison_curve.png".format(output_base))
    pyplot.show()
    pyplot.close()
//  [python]
def log_kdes(self, tag, data, save_img=False):
        """
        requires data to be:
        {'data1': {'x': x, 'y': y}, 'data2': {'x': x, 'y': y}, ..}
        """
        def np_val(x):
            return x.cpu().numpy().squeeze() if isinstance(x, torch.Tensor) else x.squeeze()

        fig, ax = plt.subplots(1, len(data), figsize=(5 * len(data), 3), sharex=True, sharey=True)
        for i, (name, covariates) in enumerate(data.items()):
            try:
                if len(covariates) == 1:
                    (x_n, x), = tuple(covariates.items())
                    sns.kdeplot(x=np_val(x), ax=ax[i], shade=True, thresh=0.05)
                elif len(covariates) == 2:
                    (x_n, x), (y_n, y) = tuple(covariates.items())
                    sns.kdeplot(x=np_val(x), y=np_val(y), ax=ax[i], shade=True, thresh=0.05)
                    ax[i].set_ylabel(y_n)
                else:
                    raise ValueError(f'got too many values: {len(covariates)}')
            except np.linalg.LinAlgError:
                print(f'got a linalg error when plotting {tag}/{name}')

            ax[i].set_title(name)
            ax[i].set_xlabel(x_n)

        sns.despine()

        if save_img:
            p = os.path.join(self.trainer.logger.experiment.log_dir, f'{tag}.png')
            plt.savefig(p, dpi=300)

        self.logger.experiment.add_figure(tag, fig, self.current_epoch)
//  [python]
def log_kdes(self, tag, data, save_img=False):
        """
        requires data to be:
        {'data1': {'x': x, 'y': y}, 'data2': {'x': x, 'y': y}, ..}
        """
        def np_val(x):
            return x.cpu().numpy().squeeze() if isinstance(x, torch.Tensor) else x.squeeze()

        fig, ax = plt.subplots(1, len(data), figsize=(5 * len(data), 3), sharex=True, sharey=True)
        for i, (name, covariates) in enumerate(data.items()):
            try:
                if len(covariates) == 1:
                    (x_n, x), = tuple(covariates.items())
                    sns.kdeplot(x=np_val(x), ax=ax[i], shade=True, thresh=0.05)
                elif len(covariates) == 2:
                    (x_n, x), (y_n, y) = tuple(covariates.items())
                    sns.kdeplot(x=np_val(x), y=np_val(y), ax=ax[i], shade=True, thresh=0.05)
                    ax[i].set_ylabel(y_n)
                else:
                    raise ValueError(f'got too many values: {len(covariates)}')
            except np.linalg.LinAlgError:
                print(f'got a linalg error when plotting {tag}/{name}')

            ax[i].set_title(name)
            ax[i].set_xlabel(x_n)

        sns.utils.despine()

        if save_img:
            p = os.path.join(self.trainer.logger.experiment.log_dir, f'{tag}.png')
            plt.savefig(p, dpi=300)

        self.logger.experiment.add_figure(tag, fig, self.current_epoch)
//  [python]
def corr_by_agebin(measure_dict_dict, paper_dir, x_measure='Degree_CT_covar_ones_all_COST_10', y_measure='CT_all_slope_age', ax=None, fig=None, label=None):

    y = np.array(measure_dict_dict['COMPLETE_EXCLBAD'][y_measure])

    m_array = np.zeros(5)
    r_array = np.zeros(5)
    p_array = np.zeros(5)

    for i, age_bin in enumerate(range(1,6)):
        cohort = 'AGE_BIN_{}_EXCLBAD'.format(age_bin)
        print(cohort)
        measure_dict = measure_dict_dict[cohort]
        x = np.array(measure_dict[x_measure])

        m,c,r,p,sterr,p_perm = permutation_correlation(x, y)
        m_array[i] = m
        r_array[i] = r
        p_array[i] = p

    if not ax:
        fig, ax = plt.subplots()

    ax.plot(range(1,6), m_array, c='b')
    ax.scatter(range(1,6), m_array, s=70, c='b')
    ax.ticklabel_format(axis='y', style='sci', scilimits=(-2,2))
    if label:
        ax.set_ylabel(label)
    ax.set_xticklabels(['', '14-15', '16-17', '18-19', '20-21', '22-24'], rotation=45)

    sns.despine()

    return ax
//  [python]
def corr_by_agebin(measure_dict_dict, paper_dir, x_measure='Degree_CT_covar_ones_all_COST_10', y_measure='CT_all_slope_age', ax=None, fig=None, label=None):

    y = np.array(measure_dict_dict['COMPLETE_EXCLBAD'][y_measure])

    m_array = np.zeros(5)
    r_array = np.zeros(5)
    p_array = np.zeros(5)

    for i, age_bin in enumerate(range(1,6)):
        cohort = 'AGE_BIN_{}_EXCLBAD'.format(age_bin)
        print(cohort)
        measure_dict = measure_dict_dict[cohort]
        x = np.array(measure_dict[x_measure])

        m,c,r,p,sterr,p_perm = permutation_correlation(x, y)
        m_array[i] = m
        r_array[i] = r
        p_array[i] = p

    if not ax:
        fig, ax = plt.subplots()

    ax.plot(range(1,6), m_array, c='b')
    ax.scatter(range(1,6), m_array, s=70, c='b')
    ax.ticklabel_format(axis='y', style='sci', scilimits=(-2,2))
    if label:
        ax.set_ylabel(label)
    ax.set_xticklabels(['', '14-15', '16-17', '18-19', '20-21', '22-24'], rotation=45)

    sns.utils.despine()

    return ax
//  [python]
def candidate_histogram(measure_dict, covars_name='none', measure='PLS1_SZ', figure_name=None, ax=None, figure=None):

    # Get the sub_dict
    sub_dict = measure_dict['308']['COVARS_{}'.format(covars_name)]

    # And the data you care about
    stat = sub_dict[measure]

    # Get the variable names
    axis_label_dict = get_axis_label_dict()

    # Create the figure if you need to
    if not ax:
        # Create a figure
        fig, ax = plt.subplots(figsize=(10, 10), facecolor='white')
        # Set the seaborn context and style
        sns.set(style="white")
        sns.set_context("poster", font_scale=1.5)
    else:
        if figure is None:
            fig = plt.gcf()
        else:
            fig = figure

    # Plot all the permuted values
    ax = sns.distplot(stat[1:], ax=ax)

    # Add a line representing the true value
    ax.axvline(np.percentile(stat[1:], 95), c=sns.color_palette()[0])

    # Add a dot representing the true value
    y_min, y_max = ax.get_ylim()
    y_range = y_max - y_min
    ax.plot(stat[0], y_min + y_range/4.0, 'o', c=sns.color_palette()[2])

    # Despine because we all agree it looks better that way
    sns.despine()

    if figure_name:
        # Do the tight layout because, again, it looks better!
        fig.tight_layout()

        # And save the figure
        fig.savefig(figure_name, bbox_inches=0, dpi=100)
        plt.close(fig)

    else:
        return ax
//  [python]
def candidate_histogram(measure_dict, covars_name='none', measure='PLS1_SZ', figure_name=None, ax=None, figure=None):

    # Get the sub_dict
    sub_dict = measure_dict['308']['COVARS_{}'.format(covars_name)]

    # And the data you care about
    stat = sub_dict[measure]

    # Get the variable names
    axis_label_dict = get_axis_label_dict()

    # Create the figure if you need to
    if not ax:
        # Create a figure
        fig, ax = plt.subplots(figsize=(10, 10), facecolor='white')
        # Set the seaborn context and style
        sns.set(style="white")
        sns.set_context("poster", font_scale=1.5)
    else:
        if figure is None:
            fig = plt.gcf()
        else:
            fig = figure

    # Plot all the permuted values
    ax = sns.distplot(stat[1:], ax=ax)

    # Add a line representing the true value
    ax.axvline(np.percentile(stat[1:], 95), c=sns.color_palette()[0])

    # Add a dot representing the true value
    y_min, y_max = ax.get_ylim()
    y_range = y_max - y_min
    ax.plot(stat[0], y_min + y_range/4.0, 'o', c=sns.color_palette()[2])

    # Despine because we all agree it looks better that way
    sns.utils.despine()

    if figure_name:
        # Do the tight layout because, again, it looks better!
        fig.tight_layout()

        # And save the figure
        fig.savefig(figure_name, bbox_inches=0, dpi=100)
        plt.close(fig)

    else:
        return ax
//  [python]
def plot_simulation_output(df: pd.DataFrame, target_location: str):
    df = df[["S", "E", "I", "R", "E+I", "E+I+R"]]

    fig1 = plt.figure()
    sns.despine()
    plt.grid()
    ax = sns.lineplot(data=df)
    ax.set_title("Visão Geral da Epidemia")

    fig2 = plt.figure()
    sns.despine()
    plt.grid()
    ax = sns.lineplot(data=df[["E", "I", "E+I", "E+I+R"]])
    ax.set_title("Apenas Expostos e Infectados")

    zoom_length = 30
    peak_date = df["I"].idxmax().date()
    zoom_on = (pd.Timestamp(peak_date) - pd.DateOffset(days=zoom_length)).date()

    zoom_end = (pd.Timestamp(peak_date) + pd.DateOffset(days=zoom_length)).date()
    fig3 = plt.figure()
    sns.despine()
    plt.grid()
    ax = sns.lineplot(
        data=df[["E", "I", "E+I"]][zoom_on:zoom_end], markers=True
    )
    ax.set_title(f"Zoom (de {zoom_on} a {zoom_end})")
    plt.xticks(fontsize=8, rotation=30)

    return st.markdown(f"# Modelo SEIR - {target_location}"), st.pyplot(fig1), st.pyplot(fig2), st.pyplot(fig3)
//  [python]
def plot_simulation_output(df: pd.DataFrame, target_location: str):
    df = df[["S", "E", "I", "R", "E+I", "E+I+R"]]

    fig1 = plt.figure()
    sns.utils.despine()
    plt.grid()
    ax = sns.lineplot(data=df)
    ax.set_title("Visão Geral da Epidemia")

    fig2 = plt.figure()
    sns.utils.despine()
    plt.grid()
    ax = sns.lineplot(data=df[["E", "I", "E+I", "E+I+R"]])
    ax.set_title("Apenas Expostos e Infectados")

    zoom_length = 30
    peak_date = df["I"].idxmax().date()
    zoom_on = (pd.Timestamp(peak_date) - pd.DateOffset(days=zoom_length)).date()

    zoom_end = (pd.Timestamp(peak_date) + pd.DateOffset(days=zoom_length)).date()
    fig3 = plt.figure()
    sns.utils.despine()
    plt.grid()
    ax = sns.lineplot(
        data=df[["E", "I", "E+I"]][zoom_on:zoom_end], markers=True
    )
    ax.set_title(f"Zoom (de {zoom_on} a {zoom_end})")
    plt.xticks(fontsize=8, rotation=30)

    return st.markdown(f"# Modelo SEIR - {target_location}"), st.pyplot(fig1), st.pyplot(fig2), st.pyplot(fig3)
//  [python]
def make_plot_despine(ax):
    sns.despine(ax=ax, offset=10)
    ax.set_xlim([0, 3.5])
    ax.set_ylim([0, 3.5])
    ax.set_xticks(np.arange(0, 3.6, 0.5))
    ax.set_yticks(np.arange(0, 3.6, 0.5))
    ax.set_xlabel(r"$X_1$")
    ax.set_ylabel(r"$X_2$")
    ax.legend(loc="upper left", fontsize=16)
//  [python]
def make_plot_despine(ax):
    sns.utils.despine(ax=ax, offset=10)
    ax.set_xlim([0, 3.5])
    ax.set_ylim([0, 3.5])
    ax.set_xticks(np.arange(0, 3.6, 0.5))
    ax.set_yticks(np.arange(0, 3.6, 0.5))
    ax.set_xlabel(r"$X_1$")
    ax.set_ylabel(r"$X_2$")
    ax.legend(loc="upper left", fontsize=16)
//  [python]
def plot(self, file_name=None):

        # Re-add the time series index
        r = pd.Series(self.actual, index=self.index)
        q = pd.Series(self.forecast, index=self.index)

        sns.set_context("paper")
        sns.set_style("whitegrid", {"font.family": "serif", "font.serif": "Computer Modern Roman", "text.usetex": True})

        # Hits
        ax = r[r <= q].plot(color="red", marker="o", ls="None", figsize=(6, 3.5))
        for h in r[r <= q].index:
            plt.axvline(h, color="black", alpha=0.4, linewidth=1, zorder=0)

        # Positive returns
        r[q < r].plot(ax=ax, color="green", marker="o", ls="None")

        # Negative returns but no hit
        r[(q <= r) & (r <= 0)].plot(ax=ax, color="orange", marker="o", ls="None")

        # VaR
        q.plot(ax=ax, grid=False, color="black", rot=0)

        # Axes
        plt.xlabel("")
        plt.ylabel("Log Return")
        ax.yaxis.grid()

        sns.despine()
        if file_name is None:
            plt.show()
        else:
            plt.savefig(file_name, bbox_inches="tight")
        plt.close("all")
//  [python]
def plot(self, file_name=None):

        # Re-add the time series index
        r = pd.Series(self.actual, index=self.index)
        q = pd.Series(self.forecast, index=self.index)

        sns.set_context("paper")
        sns.set_style("whitegrid", {"font.family": "serif", "font.serif": "Computer Modern Roman", "text.usetex": True})

        # Hits
        ax = r[r <= q].plot(color="red", marker="o", ls="None", figsize=(6, 3.5))
        for h in r[r <= q].index:
            plt.axvline(h, color="black", alpha=0.4, linewidth=1, zorder=0)

        # Positive returns
        r[q < r].plot(ax=ax, color="green", marker="o", ls="None")

        # Negative returns but no hit
        r[(q <= r) & (r <= 0)].plot(ax=ax, color="orange", marker="o", ls="None")

        # VaR
        q.plot(ax=ax, grid=False, color="black", rot=0)

        # Axes
        plt.xlabel("")
        plt.ylabel("Log Return")
        ax.yaxis.grid()

        sns.utils.despine()
        if file_name is None:
            plt.show()
        else:
            plt.savefig(file_name, bbox_inches="tight")
        plt.close("all")
//  [python]
def plot_motifs(motifs: list, save_name: str = None):
    """
    Plot motifs. Motifs are sorted in such a way to show first lower order motifs, then higher order motifs.

    Parameters
    ----------
    motifs : list
        List of motifs to plot

    save_name : str, optional
        Name of the file to save the plot, by default None

    Raises
    ------
    ValueError
        Motifs must be a list of length 6.

    Returns
    -------
    None
    """
    if len(motifs) != 6:
        raise ValueError("Motifs must be a list of length 6.") 
    motifs = _sort_for_visualization(motifs)
    cols = ['#cd3031' if (x < 0) else '#557fa3' for x in motifs]
    g = sns.barplot(x=["I", "II", "III", "IV", "V", "VI"], y=motifs, palette=cols)
    g.axhline(0, color="black", linewidth=0.5)
    plt.ylim(-1, 1)
    plt.ylabel("Motif abundance score")
    sns.despine()
    if save_name != None:
        plt.savefig("{}".format(save_name), bbox_inches="tight")
//  [python]
def plot_motifs(motifs: list, save_name: str = None):
    """
    Plot motifs. Motifs are sorted in such a way to show first lower order motifs, then higher order motifs.

    Parameters
    ----------
    motifs : list
        List of motifs to plot

    save_name : str, optional
        Name of the file to save the plot, by default None

    Raises
    ------
    ValueError
        Motifs must be a list of length 6.

    Returns
    -------
    None
    """
    if len(motifs) != 6:
        raise ValueError("Motifs must be a list of length 6.") 
    motifs = _sort_for_visualization(motifs)
    cols = ['#cd3031' if (x < 0) else '#557fa3' for x in motifs]
    g = sns.barplot(x=["I", "II", "III", "IV", "V", "VI"], y=motifs, palette=cols)
    g.axhline(0, color="black", linewidth=0.5)
    plt.ylim(-1, 1)
    plt.ylabel("Motif abundance score")
    sns.utils.despine()
    if save_name != None:
        plt.savefig("{}".format(save_name), bbox_inches="tight")
//  [python]
def projection_plot(data, savename):

    # setup figure
    NS = len(data)  # number of species
    fig, axs = plt.subplots(NS, 2, figsize=(8, 1.5 * NS), sharey=True, sharex="col")

    # perform the two plots for each species
    for ns, species in enumerate(data):

        df = data[species]  # select species dataframe

        # shared genome fraction
        ax = axs[ns, 0]
        sdf = df["fraction of total genome length"]
        ax_boxplot(sdf, ax)

        # add species name
        ax.text(0, 0, f"{species}", weight="bold", size="small")

        # shared segment sizes
        ax = axs[ns, 1]
        sdf = df["average segment size (bp)"]
        ax_boxplot(sdf, ax)

    # add titles
    # add_column_title(axs[0, 0], "fraction of total genome length")
    # add_column_title(axs[0, 1], "average segment size (bp)")
    axs[-1, 0].set_xlabel("fraction of total genome length")
    axs[-1, 1].set_xlabel("average segment size (bp)")

    # tweak second column ax
    ax.set_xscale("log")
    axs[0, 1].set_xticks(10.0 ** np.arange(0, 7))

    # despine and save
    sns.despine(fig)
    plt.tight_layout()
    plt.savefig(savename)
    plt.close(fig)
//  [python]
def projection_plot(data, savename):

    # setup figure
    NS = len(data)  # number of species
    fig, axs = plt.subplots(NS, 2, figsize=(8, 1.5 * NS), sharey=True, sharex="col")

    # perform the two plots for each species
    for ns, species in enumerate(data):

        df = data[species]  # select species dataframe

        # shared genome fraction
        ax = axs[ns, 0]
        sdf = df["fraction of total genome length"]
        ax_boxplot(sdf, ax)

        # add species name
        ax.text(0, 0, f"{species}", weight="bold", size="small")

        # shared segment sizes
        ax = axs[ns, 1]
        sdf = df["average segment size (bp)"]
        ax_boxplot(sdf, ax)

    # add titles
    # add_column_title(axs[0, 0], "fraction of total genome length")
    # add_column_title(axs[0, 1], "average segment size (bp)")
    axs[-1, 0].set_xlabel("fraction of total genome length")
    axs[-1, 1].set_xlabel("average segment size (bp)")

    # tweak second column ax
    ax.set_xscale("log")
    axs[0, 1].set_xticks(10.0 ** np.arange(0, 7))

    # despine and save
    sns.utils.despine(fig)
    plt.tight_layout()
    plt.savefig(savename)
    plt.close(fig)
//  [python]
def plot_subfigure(x, y, prop, **kwargs):
  zorder = 3 if kwargs.get('label') == 'C++ Format' else 2
  plt.plot(x, y, marker='o', markersize=6, zorder=zorder, **kwargs)
  plt.axvline(16, ls='--', color='grey')

  xmax = max(x) + 1
  plt.xlim(0, xmax)
  plt.xticks(np.arange(0, xmax, 4))
  plt.grid(color='k', alpha=0.4, ls=':')
  sns.despine()

  plt.xlabel('number of arguments')
  if prop == 'time':
    plt.ylabel('compile time (s)')
  else:
    plt.ylabel('binary size (MiB)')
//  [python]
def plot_subfigure(x, y, prop, **kwargs):
  zorder = 3 if kwargs.get('label') == 'C++ Format' else 2
  plt.plot(x, y, marker='o', markersize=6, zorder=zorder, **kwargs)
  plt.axvline(16, ls='--', color='grey')

  xmax = max(x) + 1
  plt.xlim(0, xmax)
  plt.xticks(np.arange(0, xmax, 4))
  plt.grid(color='k', alpha=0.4, ls=':')
  sns.utils.despine()

  plt.xlabel('number of arguments')
  if prop == 'time':
    plt.ylabel('compile time (s)')
  else:
    plt.ylabel('binary size (MiB)')
//  [python]
def log_kdes(self, tag, data, save_img=False):
        def np_val(x):
            return x.cpu().numpy().squeeze() if isinstance(x, torch.Tensor) else x.squeeze()

        fig, ax = plt.subplots(1, len(data), figsize=(5 * len(data), 3), sharex=True, sharey=True)
        for i, (name, covariates) in enumerate(data.items()):
            try:
                if len(covariates) == 1:
                    (x_n, x), = tuple(covariates.items())
                    sns.histplot(x=np_val(x), ax=ax[i])
                elif len(covariates) == 2:
                    (x_n, x), (y_n, y) = tuple(covariates.items())
                    sns.histplot(x=np_val(x), y=np_val(y), ax=ax[i])
                    ax[i].set_ylabel(y_n)
                else:
                    raise ValueError(f'got too many values: {len(covariates)}')
            except Exception as e:
                logging.info(e)
                logging.info(f'Got the above error when plotting {tag}/{name}')

            ax[i].set_title(name)
            ax[i].set_xlabel(x_n)

        sns.despine()

        if save_img:
            p = os.path.join(self.trainer.logger.experiment.log_dir, f'{tag}.png')
            plt.savefig(p, dpi=300)

        self.logger.experiment.add_figure(tag, fig, self.current_epoch)
//  [python]
def log_kdes(self, tag, data, save_img=False):
        def np_val(x):
            return x.cpu().numpy().squeeze() if isinstance(x, torch.Tensor) else x.squeeze()

        fig, ax = plt.subplots(1, len(data), figsize=(5 * len(data), 3), sharex=True, sharey=True)
        for i, (name, covariates) in enumerate(data.items()):
            try:
                if len(covariates) == 1:
                    (x_n, x), = tuple(covariates.items())
                    sns.histplot(x=np_val(x), ax=ax[i])
                elif len(covariates) == 2:
                    (x_n, x), (y_n, y) = tuple(covariates.items())
                    sns.histplot(x=np_val(x), y=np_val(y), ax=ax[i])
                    ax[i].set_ylabel(y_n)
                else:
                    raise ValueError(f'got too many values: {len(covariates)}')
            except Exception as e:
                logging.info(e)
                logging.info(f'Got the above error when plotting {tag}/{name}')

            ax[i].set_title(name)
            ax[i].set_xlabel(x_n)

        sns.utils.despine()

        if save_img:
            p = os.path.join(self.trainer.logger.experiment.log_dir, f'{tag}.png')
            plt.savefig(p, dpi=300)

        self.logger.experiment.add_figure(tag, fig, self.current_epoch)
//  [python]
def plot_pca(pX, palette='Spectral', labels=None, ax=None, colors=None):
    """Plot PCA result, input should be a dataframe"""

    if ax==None:
        fig,ax=plt.subplots(1,1,figsize=(6,6))
    cats = pX.index.unique()
    colors = sns.mpl_palette(palette, len(cats)+1)
    print (len(cats), len(colors))
    for c, i in zip(colors, cats):
        #print (i, len(pX.ix[i]))
        #if not i in pX.index: continue
        ax.scatter(pX.ix[i, 0], pX.ix[i, 1], color=c, s=90, label=i,
                   lw=.8, edgecolor='black', alpha=0.8)
    ax.set_xlabel('PC1')
    ax.set_ylabel('PC2')
    i=0
    if labels is not None:
        for n, point in pX.iterrows():
            l=labels[i]
            ax.text(point[0]+.1, point[1]+.1, str(l),fontsize=(9))
            i+=1
    ax.legend(fontsize=10,bbox_to_anchor=(1.5, 1.05))
    sns.despine()
    plt.tight_layout()
    return
//  [python]
def plot_pca(pX, palette='Spectral', labels=None, ax=None, colors=None):
    """Plot PCA result, input should be a dataframe"""

    if ax==None:
        fig,ax=plt.subplots(1,1,figsize=(6,6))
    cats = pX.index.unique()
    colors = sns.mpl_palette(palette, len(cats)+1)
    print (len(cats), len(colors))
    for c, i in zip(colors, cats):
        #print (i, len(pX.ix[i]))
        #if not i in pX.index: continue
        ax.scatter(pX.ix[i, 0], pX.ix[i, 1], color=c, s=90, label=i,
                   lw=.8, edgecolor='black', alpha=0.8)
    ax.set_xlabel('PC1')
    ax.set_ylabel('PC2')
    i=0
    if labels is not None:
        for n, point in pX.iterrows():
            l=labels[i]
            ax.text(point[0]+.1, point[1]+.1, str(l),fontsize=(9))
            i+=1
    ax.legend(fontsize=10,bbox_to_anchor=(1.5, 1.05))
    sns.utils.despine()
    plt.tight_layout()
    return
//  [python]
def plot_assignment_entropy(
    ad,
    title="Entropy of Metacell Assignment",
    save_as=None,
    show=True,
    bins=None,
    figsize=(5, 5),
):
    """Plot the distribution of assignment entropy over all cells.

    Each cell is assigned with a partial weight
    to a Metacell, and these weights can be used to compute the entropy of assignment as a proxy for confidence
    of each Metacell assignment - lower entropy assignments are more confidence than high entropy assignments.

    :param ad: annData containing 'Metacells_Entropy' column in .obs
    :param title: (str) title for figure
    :param save_as: (str or None) file name to which figure is saved
    :param bins: (int) number of bins for histogram
    :param figsize: (int,int) tuple of integers representing figure size
    :return:
    """
    plt.figure(figsize=figsize)
    sns.distplot(ad.obs["Metacell_Entropy"], bins=bins)
    plt.title(title)
    sns.despine()

    if save_as is not None:
        plt.savefig(save_as, dpi=150, transparent=True)
    if show:
        plt.show()
    plt.close()