jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def draw_stripplot(
    df,
    x,
    y,
    hue,
    xscale="linear",
    xbound=None,
    hue_order=None,
    xlabel=None,
    ylabel=None,
    y_labels=None,
    title=None,
    legend_title=None,
    legend_loc="best",
    legend_labels=None,
    colormap="colorblind",
    size=None,
):
    with sb.axes_style(
        "whitegrid",
        rc={
            "grid.linestyle": "dotted",
            "font.family": "serif",
            "font.serif": "Times New Roman",
        },
    ), sb.plotting_context("paper"):
        # print(sb.axes_style())
        # Initialize the figure
        strip_fig, axes = mp.pyplot.subplots(
            dpi=120, figsize=size or (10, len(df.index.unique()))
        )
        set_scales(axes, xscale=xscale)
        if xbound is not None:
            axes.set_autoscalex_on(False)
            axes.set_xbound(*xbound)
            # axes.invert_xaxis()
        sb.utils.despine(bottom=True, left=True)

        # Show each observation with a scatterplot
        sb.stripplot(
            data=df,
            x=x,
            y=y,
            hue=hue,
            hue_order=hue_order,
            palette=colormap,
            dodge=True,
            jitter=False,
            alpha=0.15,
            zorder=1,
            linewidth=0.2,
        )

        # Show the conditional means
        sb.pointplot(
            data=df,
            x=x,
            y=y,
            hue=hue,
            hue_order=hue_order,
            palette=colormap,
            dodge=0.5,
            join=False,
            markers="d",
            scale=1.1,
            ci=None,
        )

        # Improve the legend
        handles, labels = axes.get_legend_handles_labels()
        dist = int(len(labels) / 2)
        handles, labels = handles[dist:], labels[dist:]
        if legend_labels is not None:
            if isinstance(legend_labels, list):
                labels = legend_labels
            else:
                labels = map(legend_labels, labels)
        print("Legend", handles, labels)

        axes.legend(
            handles,
            labels,
            title=legend_title or hue,
            handletextpad=0,
            columnspacing=1,
            loc=legend_loc,
            ncol=1,
            frameon=True,
        )
        # draw vertical line from (70,100) to (70, 250)
        for i in range(0, 14):
            axes.plot([0, 1], [i + 0.5, i + 0.5], "--", lw=0.5, color="gray")
        axes.plot([0, 1], [13.5, 13.5], "--", lw=1.5, color="gray")
        axes.plot([0, 1], [10.5, 10.5], "--", lw=1.5, color="gray")

        # axes.get_legend().remove()
        set_labels(axes, title=title, xlabel=xlabel, ylabel=ylabel, y_labels=y_labels)
        return strip_fig
//  [python]
def plot_degree_betweenness(G):
    """Plot scatterplot between degree and betweenness centrality."""
    bc = pd.Series(nx.betweenness_centrality(G))
    dc = pd.Series(nx.degree_centrality(G))

    df = pd.DataFrame(dict(bc=bc, dc=dc))
    ax = df.plot(x="dc", y="bc", kind="scatter")
    ax.set_ylabel("Betweenness\nCentrality")
    ax.set_xlabel("Degree Centrality")
    sns.despine()
//  [python]
def plot_degree_betweenness(G):
    """Plot scatterplot between degree and betweenness centrality."""
    bc = pd.Series(nx.betweenness_centrality(G))
    dc = pd.Series(nx.degree_centrality(G))

    df = pd.DataFrame(dict(bc=bc, dc=dc))
    ax = df.plot(x="dc", y="bc", kind="scatter")
    ax.set_ylabel("Betweenness\nCentrality")
    ax.set_xlabel("Degree Centrality")
    sns.utils.despine()
//  [python]
def plot_mash_dendrogram(Mdb, Cdb, linkage, threshold=False, plot_dir=False):
    '''
    Make a dendrogram of the primary clustering

    Args:
        Mdb: DataFrame of Mash comparison results
        Cdb: DataFrame of Clustering results
        linkage: Result of scipy.cluster.hierarchy.linkage
        threshold (optional): Line to plot on x-axis
        plot_dir (optional): Location to store plot

    Returns:
        Makes and shows plot
    '''
    sns.set_style('white',{'axes.grid': False})

    db = Mdb.pivot("genome1","genome2","similarity")
    names = list(db.columns)
    name2cluster = Cdb.set_index('genome')['primary_cluster'].to_dict()
    name2color = gen_color_dict(names, name2cluster)

    # Make the dendrogram
    g = fancy_dendrogram_(linkage,names,name2color,threshold=threshold)
    plt.title('MASH clustering')
    plt.xlabel('MASH Average Nucleotide Identity (ANI)')
    #plt.xlim([0,.4])

    sns.despine(left=True,top=True,right=True,bottom=False)

    # Adjust the figure size
    fig = plt.gcf()
    fig.set_size_inches(10,_x_fig_size(len(names),factor=.2))
    plt.subplots_adjust(left=0.3)

    # Adjust the x labels
    plt.tick_params(axis='both', which='major', labelsize=8)
    axes = plt.gca()
    labels = axes.xaxis.get_majorticklocs()
    for i, label in enumerate(labels):
        labels[i] = (1 - float(label)) * 100
    axes.set_xticklabels(labels)

    # Add cluster to the y axis
    g2c = Cdb.set_index('genome')['secondary_cluster'].to_dict()
    axes = plt.gca()
    labels = [item.get_text() for item in axes.get_yticklabels()]
    for i, label in enumerate(labels):
        labels[i] = "{0} ({1})".format(label, g2c[label])
    axes.set_yticklabels(labels)

    # Save the figure
    if plot_dir != None:
        plt.savefig(os.path.join(plot_dir, 'Primary_clustering_dendrogram_truncate.pdf'),\
            format="pdf", transparent=True, bbox_inches='tight')
    plt.show()
    plt.close('all')
//  [python]
def plot_mash_dendrogram(Mdb, Cdb, linkage, threshold=False, plot_dir=False):
    '''
    Make a dendrogram of the primary clustering

    Args:
        Mdb: DataFrame of Mash comparison results
        Cdb: DataFrame of Clustering results
        linkage: Result of scipy.cluster.hierarchy.linkage
        threshold (optional): Line to plot on x-axis
        plot_dir (optional): Location to store plot

    Returns:
        Makes and shows plot
    '''
    sns.set_style('white',{'axes.grid': False})

    db = Mdb.pivot("genome1","genome2","similarity")
    names = list(db.columns)
    name2cluster = Cdb.set_index('genome')['primary_cluster'].to_dict()
    name2color = gen_color_dict(names, name2cluster)

    # Make the dendrogram
    g = fancy_dendrogram_(linkage,names,name2color,threshold=threshold)
    plt.title('MASH clustering')
    plt.xlabel('MASH Average Nucleotide Identity (ANI)')
    #plt.xlim([0,.4])

    sns.utils.despine(left=True,top=True,right=True,bottom=False)

    # Adjust the figure size
    fig = plt.gcf()
    fig.set_size_inches(10,_x_fig_size(len(names),factor=.2))
    plt.subplots_adjust(left=0.3)

    # Adjust the x labels
    plt.tick_params(axis='both', which='major', labelsize=8)
    axes = plt.gca()
    labels = axes.xaxis.get_majorticklocs()
    for i, label in enumerate(labels):
        labels[i] = (1 - float(label)) * 100
    axes.set_xticklabels(labels)

    # Add cluster to the y axis
    g2c = Cdb.set_index('genome')['secondary_cluster'].to_dict()
    axes = plt.gca()
    labels = [item.get_text() for item in axes.get_yticklabels()]
    for i, label in enumerate(labels):
        labels[i] = "{0} ({1})".format(label, g2c[label])
    axes.set_yticklabels(labels)

    # Save the figure
    if plot_dir != None:
        plt.savefig(os.path.join(plot_dir, 'Primary_clustering_dendrogram_truncate.pdf'),\
            format="pdf", transparent=True, bbox_inches='tight')
    plt.show()
    plt.close('all')
//  [python]
def plot_bar_gene_expression(self, gene_names, nrow=None, ncol=None, ylim=None, figsize=(5,5),cmap=None):
        def _bar_plot(name,ylim=None,ax=None):
            expr = self.get_expr_for_gene(name, scaled=False).values        
            #plt.title(name)
            d = pd.DataFrame(np.array([expr, self._clusts]).T, columns=["expr", "cluster"])
            if cmap is None:
                sns.barplot(x="cluster", y="expr", data=d, ax=ax) 
            else:
                sns.barplot(x="cluster", y="expr", data=d, ax=ax,palette=cmap)
            if ax is None:
                ax = plt.axes()
            ax.set_title(name)
            if ylim is not None:
                ax.set_ylim([-1, ylim])
            sns.despine(ax=ax)
            ax.set_xlabel("")
            ax.get_xaxis().set_visible(False)
            ax.get_yaxis().set_visible(False)
        if isinstance(gene_names, list):
            if nrow is None and ncol is None:
                nrow = np.ceil(np.sqrt(len(gene_names)))
                ncol = nrow
            f,ax = plt.subplots(int(nrow), int(ncol),figsize=figsize)
            f.tight_layout()
            ax = np.array(ax).flatten()
            for i, name in enumerate(gene_names):
                _bar_plot(name,ylim,ax=ax[i])
        else:
            _bar_plot(gene_names,ylim)
//  [python]
def plot_bar_gene_expression(self, gene_names, nrow=None, ncol=None, ylim=None, figsize=(5,5),cmap=None):
        def _bar_plot(name,ylim=None,ax=None):
            expr = self.get_expr_for_gene(name, scaled=False).values        
            #plt.title(name)
            d = pd.DataFrame(np.array([expr, self._clusts]).T, columns=["expr", "cluster"])
            if cmap is None:
                sns.barplot(x="cluster", y="expr", data=d, ax=ax) 
            else:
                sns.barplot(x="cluster", y="expr", data=d, ax=ax,palette=cmap)
            if ax is None:
                ax = plt.axes()
            ax.set_title(name)
            if ylim is not None:
                ax.set_ylim([-1, ylim])
            sns.utils.despine(ax=ax)
            ax.set_xlabel("")
            ax.get_xaxis().set_visible(False)
            ax.get_yaxis().set_visible(False)
        if isinstance(gene_names, list):
            if nrow is None and ncol is None:
                nrow = np.ceil(np.sqrt(len(gene_names)))
                ncol = nrow
            f,ax = plt.subplots(int(nrow), int(ncol),figsize=figsize)
            f.tight_layout()
            ax = np.array(ax).flatten()
            for i, name in enumerate(gene_names):
                _bar_plot(name,ylim,ax=ax[i])
        else:
            _bar_plot(gene_names,ylim)
//  [python]
def diagnostic_extreme_removal(
    mad_validator: MADValidator,
    raw_data: pd.DataFrame,
    col: str,
):
    """
    Creates a diagnostic plot for the extreme value removal procedure.

    Parameters:
    ----------
    mad_validator: sam.validation.MADValidator
        fitted MADValidator object
    raw_data: pd.DataFrame
        non-transformed data data
    col: string
        column name to plot

    Returns:
    -------
    fig: matplotlib.pyplot.figure
        diagnostic plot
    """
    import matplotlib.pyplot as plt
    import seaborn as sns

    # get data
    x = raw_data[col].copy()
    invalid_w = mad_validator.validate(raw_data)[col]
    invalid_values = x.loc[invalid_w]
    rolling = mad_validator._compute_rolling(x)
    diff = x.values - rolling

    # generate plot
    fig = plt.figure(figsize=(12, 6))
    plt.subplot(211)
    plt.title(col)

    plt.plot(x.index, x.values, label="original_signal", lw=5)

    plt.plot(
        rolling.index,
        rolling.values,
        "--k",
        label="rolling median",
        lw=3,
    )

    plt.plot(
        invalid_values.index,
        invalid_values.values,
        "o",
        ms=10,
        mew=2,
        mec="r",
        fillstyle="none",
        label="invalid samples",
    )

    plt.legend(loc="best")
    sns.despine()

    plt.subplot(212)
    plt.plot(diff.values, label="abs(original - rolling)")
    plt.axhline(mad_validator.thresh_high[col], ls="--", c="r")
    plt.axhline(mad_validator.thresh_low[col], ls="--", c="r", label="thresholds")
    plt.legend(loc="best")
    sns.despine()
    plt.tight_layout()

    return fig
//  [python]
def diagnostic_extreme_removal(
    mad_validator: MADValidator,
    raw_data: pd.DataFrame,
    col: str,
):
    """
    Creates a diagnostic plot for the extreme value removal procedure.

    Parameters:
    ----------
    mad_validator: sam.validation.MADValidator
        fitted MADValidator object
    raw_data: pd.DataFrame
        non-transformed data data
    col: string
        column name to plot

    Returns:
    -------
    fig: matplotlib.pyplot.figure
        diagnostic plot
    """
    import matplotlib.pyplot as plt
    import seaborn as sns

    # get data
    x = raw_data[col].copy()
    invalid_w = mad_validator.validate(raw_data)[col]
    invalid_values = x.loc[invalid_w]
    rolling = mad_validator._compute_rolling(x)
    diff = x.values - rolling

    # generate plot
    fig = plt.figure(figsize=(12, 6))
    plt.subplot(211)
    plt.title(col)

    plt.plot(x.index, x.values, label="original_signal", lw=5)

    plt.plot(
        rolling.index,
        rolling.values,
        "--k",
        label="rolling median",
        lw=3,
    )

    plt.plot(
        invalid_values.index,
        invalid_values.values,
        "o",
        ms=10,
        mew=2,
        mec="r",
        fillstyle="none",
        label="invalid samples",
    )

    plt.legend(loc="best")
    sns.utils.despine()

    plt.subplot(212)
    plt.plot(diff.values, label="abs(original - rolling)")
    plt.axhline(mad_validator.thresh_high[col], ls="--", c="r")
    plt.axhline(mad_validator.thresh_low[col], ls="--", c="r", label="thresholds")
    plt.legend(loc="best")
    sns.utils.despine()
    plt.tight_layout()

    return fig
//  [python]
def plot_effective_throughput_ratios(all_effective_throughputs, cdf=False,
                                     output_filename=None):
    plt.figure(figsize=(6.5, 3))
    ax = plt.subplot2grid((1, 1), (0, 0), colspan=1)
    job_ids = list(all_effective_throughputs[0].keys())
    for (effective_throughputs, label) in zip(
        all_effective_throughputs[1:], ['4 sub-clusters', '16 sub-clusters']):
        effective_throughput_ratios = [
            effective_throughputs[job_id] / all_effective_throughputs[0][job_id]
            for job_id in job_ids]
        if cdf:
            ax.plot([float((i+1) * 100.0) / len(effective_throughputs)
                     for i in range(len(effective_throughputs))],
                    sorted(effective_throughput_ratios), label=label)
        else:
            ax.plot(range(len(effective_throughputs)),
                    effective_throughput_ratios, label=label)
    ax.axhline(1.0, color='k', linestyle=':', linewidth=2)
    if cdf:
        ax.set_xlabel("CDF (%)")
    else:
        ax.set_xlabel("Job ID")
    ax.set_ylabel("Effective\nthroughput ratio")
    if cdf:
        ax.set_xlim([0, 100.0])
    else:
        ax.set_xlim([0, len(effective_throughputs)])
    ax.set_ylim([0, 2.0])
    plt.legend(frameon=False)
    sns.despine()
    
    if output_filename is not None:
        with PdfPages(output_filename) as pdf:
            pdf.savefig(bbox_inches='tight')
            
    plt.show()
//  [python]
def plot_effective_throughput_ratios(all_effective_throughputs, cdf=False,
                                     output_filename=None):
    plt.figure(figsize=(6.5, 3))
    ax = plt.subplot2grid((1, 1), (0, 0), colspan=1)
    job_ids = list(all_effective_throughputs[0].keys())
    for (effective_throughputs, label) in zip(
        all_effective_throughputs[1:], ['4 sub-clusters', '16 sub-clusters']):
        effective_throughput_ratios = [
            effective_throughputs[job_id] / all_effective_throughputs[0][job_id]
            for job_id in job_ids]
        if cdf:
            ax.plot([float((i+1) * 100.0) / len(effective_throughputs)
                     for i in range(len(effective_throughputs))],
                    sorted(effective_throughput_ratios), label=label)
        else:
            ax.plot(range(len(effective_throughputs)),
                    effective_throughput_ratios, label=label)
    ax.axhline(1.0, color='k', linestyle=':', linewidth=2)
    if cdf:
        ax.set_xlabel("CDF (%)")
    else:
        ax.set_xlabel("Job ID")
    ax.set_ylabel("Effective\nthroughput ratio")
    if cdf:
        ax.set_xlim([0, 100.0])
    else:
        ax.set_xlim([0, len(effective_throughputs)])
    ax.set_ylim([0, 2.0])
    plt.legend(frameon=False)
    sns.utils.despine()
    
    if output_filename is not None:
        with PdfPages(output_filename) as pdf:
            pdf.savefig(bbox_inches='tight')
            
    plt.show()
//  [python]
g = sns.FacetGrid(data=res, col='location', col_wrap=4, size=3, sharex=True,
                    sharey=False)

# Map a histogram for each location
g.map(plt.hist, "value")

# Set the titles
g.set_titles("{col_name}")

# Set the axis labels
g.set_axis_labels("$PM_{2.5}$ [$\mu g m^{-3}$]", None)

# Remove the left axis
sns.despine(left=True)
//  [python]
g = sns.FacetGrid(data=res, col='location', col_wrap=4, size=3, sharex=True,
                    sharey=False)

# Map a histogram for each location
g.map(plt.hist, "value")

# Set the titles
g.set_titles("{col_name}")

# Set the axis labels
g.set_axis_labels("$PM_{2.5}$ [$\mu g m^{-3}$]", None)

# Remove the left axis
sns.utils.despine(left=True)
//  [python]
def plot_runtime_vs_effective_throughput_ratios(runtimes, all_effective_throughputs, labels,
                                                draw_arrow=False,
                                                output_filename=None):
    plt.figure(figsize=(6.5, 3))
    ax = plt.subplot2grid((1, 1), (0, 0), colspan=1)
    job_ids = list(all_effective_throughputs[0].keys())
    for (runtime, effective_throughputs, label) in zip(
        runtimes,
        all_effective_throughputs,
        labels):
        effective_throughput_ratios = np.array([
            effective_throughputs[job_id] / all_effective_throughputs[0][job_id]
            for job_id in job_ids])
        mean = np.mean(effective_throughput_ratios)
        print(label, runtime, mean, np.std(effective_throughput_ratios))
        ax.scatter(runtime, mean, label=label)
        ax.errorbar(runtime, mean, np.std(effective_throughput_ratios))
        ax.annotate(label, (runtime*1.15, mean-0.08))

    ax.set_ylabel("Throughput ratio")
    ax.set_xlabel("Runtime (seconds)")
    sns.despine()
    
    ax.set_xscale('log')
    ax.set_yticks([0.0, 0.25, 0.5, 0.75, 1.0])
    xmin, xmax = plt.xlim()
    ymin, ymax = plt.ylim()
    plt.xlim(xmin, xmax*1.2)
    plt.ylim(0, ymax*1.15)
    
    if draw_arrow:
        ax.annotate('Ideal', xy=(300, 0.8), xytext=(900, 0.3), 
            arrowprops=dict(facecolor='black', shrink=0.),
        )
    
    if output_filename is not None:
        with PdfPages(output_filename) as pdf:
            pdf.savefig(bbox_inches='tight')
            
    plt.show()
//  [python]
def plot_runtime_vs_effective_throughput_ratios(runtimes, all_effective_throughputs, labels,
                                                draw_arrow=False,
                                                output_filename=None):
    plt.figure(figsize=(6.5, 3))
    ax = plt.subplot2grid((1, 1), (0, 0), colspan=1)
    job_ids = list(all_effective_throughputs[0].keys())
    for (runtime, effective_throughputs, label) in zip(
        runtimes,
        all_effective_throughputs,
        labels):
        effective_throughput_ratios = np.array([
            effective_throughputs[job_id] / all_effective_throughputs[0][job_id]
            for job_id in job_ids])
        mean = np.mean(effective_throughput_ratios)
        print(label, runtime, mean, np.std(effective_throughput_ratios))
        ax.scatter(runtime, mean, label=label)
        ax.errorbar(runtime, mean, np.std(effective_throughput_ratios))
        ax.annotate(label, (runtime*1.15, mean-0.08))

    ax.set_ylabel("Throughput ratio")
    ax.set_xlabel("Runtime (seconds)")
    sns.utils.despine()
    
    ax.set_xscale('log')
    ax.set_yticks([0.0, 0.25, 0.5, 0.75, 1.0])
    xmin, xmax = plt.xlim()
    ymin, ymax = plt.ylim()
    plt.xlim(xmin, xmax*1.2)
    plt.ylim(0, ymax*1.15)
    
    if draw_arrow:
        ax.annotate('Ideal', xy=(300, 0.8), xytext=(900, 0.3), 
            arrowprops=dict(facecolor='black', shrink=0.),
        )
    
    if output_filename is not None:
        with PdfPages(output_filename) as pdf:
            pdf.savefig(bbox_inches='tight')
            
    plt.show()
//  [python]
plt.figure(figsize=(5, 5))
plt.scatter(x, y)
plt.xticks([])
plt.yticks([])
sns.despine(left=True, bottom=True, right=True)
//  [python]
def plot_distributions_compare(prop, func, smiles, train_smiles, mm, both=True):
    mm.NORMALIZE = False
    y = func(smiles, train_smiles)
    sns.distplot(y)
    stats_box(y)
    plt.xlabel(prop)
    sns.despine(offset=True)
    plt.show()
    if both:
        mm.NORMALIZE = True
        y = func(smiles, train_smiles)
        sns.distplot(y)
        stats_box(y)
        plt.xlabel(prop + ' normalized')
        sns.despine(offset=True)
        plt.show()
    return
//  [python]
def plot_distributions_compare(prop, func, smiles, train_smiles, mm, both=True):
    mm.NORMALIZE = False
    y = func(smiles, train_smiles)
    sns.distplot(y)
    stats_box(y)
    plt.xlabel(prop)
    sns.utils.despine(offset=True)
    plt.show()
    if both:
        mm.NORMALIZE = True
        y = func(smiles, train_smiles)
        sns.distplot(y)
        stats_box(y)
        plt.xlabel(prop + ' normalized')
        sns.utils.despine(offset=True)
        plt.show()
    return
//  [python]
def plot_gender_hbars(genderDF, topics, ordered_topics_dict):
    """Plot horizontal bars showing the mean topic distribution per dominant source gender"""
    top_val = max(max(genderDF['male']), max(genderDF['female']))
    top_n_words = get_top_n_words(ordered_topics_dict)
    # Initialize the matplotlib figure
    fig, ax = plt.subplots(figsize=(8, 8))

    sns.set(style="whitegrid")

    sns.barplot(data=genderDF[['topic', 'female_reversed']],
                x='female_reversed', y='topic',
                label='Female sources > male sources',
                orient='h',
                color="#af1858",  # rgb(175, 24, 88)
                ci=None)

    sns.barplot(data=genderDF[['topic', 'male']],
                x='male', y='topic',
                label='Male sources > female sources',
                orient='h',
                color="#004d72",  # rgb(0, 77, 114)
                ci=None)

    # Add a legend and informative axis label
    ax.legend(ncol=2, loc="upper center",
              bbox_to_anchor=(0.5, 1.01), frameon=True)
    ax.set(xlim=(-top_val, top_val), ylabel="",
           xlabel="Mean Topic Weight")
    ax.set_yticklabels(top_n_words, rotation=0, fontsize=12)
    ax.xaxis.grid(False)
    # ax.yaxis.grid(True)

    sns.despine(left=True, bottom=True)
    st = fig.suptitle("Begin Date: {}  End Date: {}".format(
        topics['params']['begin_date'],
        topics['params']['end_date']),
        y=0.92
    )
    plt.subplots_adjust(wspace=0.1, hspace=0.1)
    plt.margins(x=0.1, y=0.1)
    fig.savefig(f"fig-{prefix}-hbars.png", bbox_extra_artists=[st], bbox_inches='tight')
//  [python]
def plot_gender_hbars(genderDF, topics, ordered_topics_dict):
    """Plot horizontal bars showing the mean topic distribution per dominant source gender"""
    top_val = max(max(genderDF['male']), max(genderDF['female']))
    top_n_words = get_top_n_words(ordered_topics_dict)
    # Initialize the matplotlib figure
    fig, ax = plt.subplots(figsize=(8, 8))

    sns.set(style="whitegrid")

    sns.barplot(data=genderDF[['topic', 'female_reversed']],
                x='female_reversed', y='topic',
                label='Female sources > male sources',
                orient='h',
                color="#af1858",  # rgb(175, 24, 88)
                ci=None)

    sns.barplot(data=genderDF[['topic', 'male']],
                x='male', y='topic',
                label='Male sources > female sources',
                orient='h',
                color="#004d72",  # rgb(0, 77, 114)
                ci=None)

    # Add a legend and informative axis label
    ax.legend(ncol=2, loc="upper center",
              bbox_to_anchor=(0.5, 1.01), frameon=True)
    ax.set(xlim=(-top_val, top_val), ylabel="",
           xlabel="Mean Topic Weight")
    ax.set_yticklabels(top_n_words, rotation=0, fontsize=12)
    ax.xaxis.grid(False)
    # ax.yaxis.grid(True)

    sns.utils.despine(left=True, bottom=True)
    st = fig.suptitle("Begin Date: {}  End Date: {}".format(
        topics['params']['begin_date'],
        topics['params']['end_date']),
        y=0.92
    )
    plt.subplots_adjust(wspace=0.1, hspace=0.1)
    plt.margins(x=0.1, y=0.1)
    fig.savefig(f"fig-{prefix}-hbars.png", bbox_extra_artists=[st], bbox_inches='tight')
//  [python]
def plot_facet(self, data, color, **kwargs):
        self.args = self.prepare_arguments(data, self.x, self.y, self.z,
                                           self.levels_x, self.levels_y)
        cix = self.args.pop("cix")
        if self.z:
            self.colors = self.colorizer.get_hues(cix)
        else:
            self.colors = self.colorizer.get_palette(n=len(cix))

        self.artists = self.draw_circles(**self.args)

        ax = plt.gca()
        ax.set_aspect(1)
        ax.autoscale(True, "both", True)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        sns.despine(ax=ax, top=True, bottom=True, left=True, right=True)
//  [python]
def plot_facet(self, data, color, **kwargs):
        self.args = self.prepare_arguments(data, self.x, self.y, self.z,
                                           self.levels_x, self.levels_y)
        cix = self.args.pop("cix")
        if self.z:
            self.colors = self.colorizer.get_hues(cix)
        else:
            self.colors = self.colorizer.get_palette(n=len(cix))

        self.artists = self.draw_circles(**self.args)

        ax = plt.gca()
        ax.set_aspect(1)
        ax.autoscale(True, "both", True)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        sns.utils.despine(ax=ax, top=True, bottom=True, left=True, right=True)
//  [python]
def plot_logo(icm, logo_file_name):
    plt.close()

    fig = plt.figure()
    fig.set_size_inches(len(icm), 3)
    ax = fig.add_subplot(111)
    logomaker.Logo(icm, ax=ax, show_spines=False, baseline_width=0)
    ax.set_xticks(range(len(icm)))
    ax.set_yticks(range(0, 3))

    ax.set_xticklabels(range(1, len(icm) + 1))
    ax.set_yticklabels(np.arange(0, 3, 1))

    seaborn.despine(ax=ax, offset=10, trim=True)
    
    fig.tight_layout()
    plt.savefig(logo_file_name, dpi=300)
//  [python]
def plot_logo(icm, logo_file_name):
    plt.close()

    fig = plt.figure()
    fig.set_size_inches(len(icm), 3)
    ax = fig.add_subplot(111)
    logomaker.Logo(icm, ax=ax, show_spines=False, baseline_width=0)
    ax.set_xticks(range(len(icm)))
    ax.set_yticks(range(0, 3))

    ax.set_xticklabels(range(1, len(icm) + 1))
    ax.set_yticklabels(np.arange(0, 3, 1))

    seaborn.utils.despine(ax=ax, offset=10, trim=True)
    
    fig.tight_layout()
    plt.savefig(logo_file_name, dpi=300)
//  [python]
def write_experimental_heatmap(
    *,
    dataset: str,
    optimizer: str,
    df: pd.DataFrame,
    target_header: str,
    output_directory: str,
    name: Optional[str] = None,
    make_pngs: bool = True,
    make_pdfs: bool = True,
    font_scale: float = 1.5,
):
    g = sns.FacetGrid(
        data=df,
        row='inverse_relations',
        col='training_approach',
        despine=True,
        size=10,
        margin_titles=True,
        sharex=False,
        sharey=False,
        height=1,
    )
    rows = sorted(df['model'].unique())
    cols = sorted(df['loss'].unique())
    g.map_dataframe(_custom_heatmap, y='model', x='loss', z=target_header, rows=rows, cols=cols, cmap=None)
    # for a in g.axes[0, :]:
    #     a.set_xticks([])
    # cbar = g.fig.colorbar(g.axes[0, 0].collections[0], ax=g.axes, fraction=0.1)
    # cbar.set_label(target_header, rotation=270)
    sns.despine()
    g.fig.set_size_inches(8.3*g.axes.shape[1], 11.7*g.axes.shape[0])
    if name is None:
        name = f'{dataset}_{optimizer}_heatmap'
    if make_pngs:
        g.savefig(os.path.join(output_directory, f'{name}.png'.lower()), dpi=300)
    if make_pdfs:
        g.savefig(os.path.join(output_directory, f'{name}.pdf'.lower()))
    plt.close(g.fig)
//  [python]
def write_experimental_heatmap(
    *,
    dataset: str,
    optimizer: str,
    df: pd.DataFrame,
    target_header: str,
    output_directory: str,
    name: Optional[str] = None,
    make_pngs: bool = True,
    make_pdfs: bool = True,
    font_scale: float = 1.5,
):
    g = sns.FacetGrid(
        data=df,
        row='inverse_relations',
        col='training_approach',
        despine=True,
        size=10,
        margin_titles=True,
        sharex=False,
        sharey=False,
        height=1,
    )
    rows = sorted(df['model'].unique())
    cols = sorted(df['loss'].unique())
    g.map_dataframe(_custom_heatmap, y='model', x='loss', z=target_header, rows=rows, cols=cols, cmap=None)
    # for a in g.axes[0, :]:
    #     a.set_xticks([])
    # cbar = g.fig.colorbar(g.axes[0, 0].collections[0], ax=g.axes, fraction=0.1)
    # cbar.set_label(target_header, rotation=270)
    sns.utils.despine()
    g.fig.set_size_inches(8.3*g.axes.shape[1], 11.7*g.axes.shape[0])
    if name is None:
        name = f'{dataset}_{optimizer}_heatmap'
    if make_pngs:
        g.savefig(os.path.join(output_directory, f'{name}.png'.lower()), dpi=300)
    if make_pdfs:
        g.savefig(os.path.join(output_directory, f'{name}.pdf'.lower()))
    plt.close(g.fig)
//  [python]
def compare_hcpd_snf(hdf):
    """
    Assesses SNF clustering / embedding results when both HC + PD patients used

    Parameters
    ----------
    hdf : structures.Frog
        HDF5 file containing SNF gridsearch outputs

    Returns
    -------
    fig : matplotlib.figures.Figure
        Plotted figure
    """

    # load results from the combined PD/HC SNF gridsearch
    res = hdf['/snf/processed/pdhc/sqeuclidean/gridsearch']
    dimension1, dimension2 = res['embedding'].T[:2]
    consensus = res['consensus']

    # ground truth labels
    true = np.hstack((np.zeros(len(hdf['/raw/pd_demographics'])),
                      np.ones(len(hdf['/raw/hc_demographics']))))

    # plot scatterplot of ground truth vs HC/PD clusterings olution
    fig, axes = plt.subplots(1, 2, figsize=(10, 4), sharex=True, sharey=True)
    for ax, clusters, title in zip(axes, [true, consensus],
                                   ['Ground truth', 'SNF clustering']):
        ax.scatter(dimension1, dimension2, c=clusters, s=60, linewidth=0.5,
                   cmap=ListedColormap(defaults.three_cluster_cmap),
                   edgecolor=defaults.edgegray)
        ax.set(title=title, xlabel='dimension 1', ylabel='dimension 2',
               yticklabels=[], xticklabels=[])
        sns.despine(ax=ax)
    ax.set_ylabel('')

    # calculate F1 scores
    # for F1 the actual number representing the cluster assignment matters so
    # we need to re-number the `consensus` cluster labels to match the ground
    # truth as best as possible
    consensus = cluster.match_cluster_labels(consensus, true)
    f1_scores = metrics.f1_score(true, consensus % 2, average=None)
    print('F1 scores: PD = {:.2f}, HC = {:.2f}'.format(*f1_scores))

    return fig
//  [python]
def compare_hcpd_snf(hdf):
    """
    Assesses SNF clustering / embedding results when both HC + PD patients used

    Parameters
    ----------
    hdf : structures.Frog
        HDF5 file containing SNF gridsearch outputs

    Returns
    -------
    fig : matplotlib.figures.Figure
        Plotted figure
    """

    # load results from the combined PD/HC SNF gridsearch
    res = hdf['/snf/processed/pdhc/sqeuclidean/gridsearch']
    dimension1, dimension2 = res['embedding'].T[:2]
    consensus = res['consensus']

    # ground truth labels
    true = np.hstack((np.zeros(len(hdf['/raw/pd_demographics'])),
                      np.ones(len(hdf['/raw/hc_demographics']))))

    # plot scatterplot of ground truth vs HC/PD clusterings olution
    fig, axes = plt.subplots(1, 2, figsize=(10, 4), sharex=True, sharey=True)
    for ax, clusters, title in zip(axes, [true, consensus],
                                   ['Ground truth', 'SNF clustering']):
        ax.scatter(dimension1, dimension2, c=clusters, s=60, linewidth=0.5,
                   cmap=ListedColormap(defaults.three_cluster_cmap),
                   edgecolor=defaults.edgegray)
        ax.set(title=title, xlabel='dimension 1', ylabel='dimension 2',
               yticklabels=[], xticklabels=[])
        sns.utils.despine(ax=ax)
    ax.set_ylabel('')

    # calculate F1 scores
    # for F1 the actual number representing the cluster assignment matters so
    # we need to re-number the `consensus` cluster labels to match the ground
    # truth as best as possible
    consensus = cluster.match_cluster_labels(consensus, true)
    f1_scores = metrics.f1_score(true, consensus % 2, average=None)
    print('F1 scores: PD = {:.2f}, HC = {:.2f}'.format(*f1_scores))

    return fig
//  [python]
def write_dataset_optimizer_barplots(
    *,
    dataset: str,
    optimizer: str,
    df: pd.DataFrame,
    target_header: str,
    output_directory: str,
    name: Optional[str] = None,
    make_pngs: bool = True,
    make_pdfs: bool = True,
    font_scale: float = 1.5,
) -> None:
    """Write model summaries, but trellis it on model."""
    data = pd.DataFrame([
        {
            'model': row['model'],
            'configuration': make_config_index(row),
            'replicate': row['replicate'],
            target_header: row[target_header],
        }
        for _, row in df.iterrows()
    ])
    logger.debug('%d replicates mapped for %s/%s', len(data.index), dataset, optimizer)

    means = data.groupby('configuration')[target_header].mean().sort_values()
    logger.debug('%d means mapped for %s/%s', len(means.index), dataset, optimizer)

    with sns.plotting_context(font_scale=font_scale):
        g = sns.catplot(
            kind='bar',
            estimator=np.median,
            data=data,
            x=target_header,
            y='configuration',
            col='model',
            col_wrap=4,
            ci=None,
            # capsize=.2, # restore if you want CIs
            order=means.index,
            palette="GnBu_d",
        )
        g.set_titles(template='{col_name}')
        g.set_ylabels('')
        g.set(xlim=[0.0, 1.0])

    sns.despine()
    if name is None:
        name = f'{dataset}_{optimizer}'
    if make_pngs:
        g.savefig(os.path.join(output_directory, f'{name}.png'.lower()), dpi=300)
    if make_pdfs:
        g.savefig(os.path.join(output_directory, f'{name}.pdf'.lower()))
    plt.close(g.fig)
//  [python]
def write_dataset_optimizer_barplots(
    *,
    dataset: str,
    optimizer: str,
    df: pd.DataFrame,
    target_header: str,
    output_directory: str,
    name: Optional[str] = None,
    make_pngs: bool = True,
    make_pdfs: bool = True,
    font_scale: float = 1.5,
) -> None:
    """Write model summaries, but trellis it on model."""
    data = pd.DataFrame([
        {
            'model': row['model'],
            'configuration': make_config_index(row),
            'replicate': row['replicate'],
            target_header: row[target_header],
        }
        for _, row in df.iterrows()
    ])
    logger.debug('%d replicates mapped for %s/%s', len(data.index), dataset, optimizer)

    means = data.groupby('configuration')[target_header].mean().sort_values()
    logger.debug('%d means mapped for %s/%s', len(means.index), dataset, optimizer)

    with sns.plotting_context(font_scale=font_scale):
        g = sns.catplot(
            kind='bar',
            estimator=np.median,
            data=data,
            x=target_header,
            y='configuration',
            col='model',
            col_wrap=4,
            ci=None,
            # capsize=.2, # restore if you want CIs
            order=means.index,
            palette="GnBu_d",
        )
        g.set_titles(template='{col_name}')
        g.set_ylabels('')
        g.set(xlim=[0.0, 1.0])

    sns.utils.despine()
    if name is None:
        name = f'{dataset}_{optimizer}'
    if make_pngs:
        g.savefig(os.path.join(output_directory, f'{name}.png'.lower()), dpi=300)
    if make_pdfs:
        g.savefig(os.path.join(output_directory, f'{name}.pdf'.lower()))
    plt.close(g.fig)
//  [python]
def plot_evenness(df, output, verbose=False):
    if verbose:
        sys.stderr.write(f"{bcolors.GREEN}Plotting evenness{bcolors.ENDC}\n")
    sns.violinplot(data=df, x='kmer', y='Evenness')
    sns.despine(offset=10, trim=True)
    plt.savefig(f"{output}.evenness.png")
    plt.clf()
//  [python]
def plot_evenness(df, output, verbose=False):
    if verbose:
        sys.stderr.write(f"{bcolors.GREEN}Plotting evenness{bcolors.ENDC}\n")
    sns.violinplot(data=df, x='kmer', y='Evenness')
    sns.utils.despine(offset=10, trim=True)
    plt.savefig(f"{output}.evenness.png")
    plt.clf()
//  [python]
def results(args):
    data = []
    for seed in [1000, 2000, 3000, 4000, 5000]:
        for hp in lengths :
            lei, fresh = get_new_type(args, args.dataset, seed, hp)
            if lei is not None:
                data.append(
                    {
                        "Dataset": datasets[args.dataset],
                        "Model": "lei",
                        "hp": hp,
                        "Macro F1": lei,
                    }
                )

            if fresh is not None:
                data.append(
                    {
                        "Dataset": datasets[args.dataset],
                        "Model": "fresh",
                        "hp": hp,
                        "Macro F1": fresh,
                    }
                )

    sns.set_context("talk")
    sns.set(style="white", rc={"lines.linewidth": 1.7}, font_scale=1.5)
    data = pd.DataFrame(data)

    breakpoint()

    f, ax = plt.subplots(1, 1, figsize=(5, 2.5))
    sns.pointplot(
        x="hp",
        y="Macro F1",
        hue="Model",
        data=data[data.Dataset == datasets[args.dataset]],
        ax=ax,
        dodge=True,
        join=True,
        hue_order=["lei", "fresh"],
        palette=["blue", "red"],
        markers=["o", "D"],
        ci="sd",
        estimator=np.median,
    )
    ax.set_xlabel("")
    ax.set_title(datasets[args.dataset])
    ax.legend_ = None

    plt.ylim(args.min_scale, args.max_scale)
    plt.legend().remove()
    sns.despine()
    f.tight_layout()
    f.savefig(f"human_prob_{args.dataset}.pdf", bbox_inches="tight")
//  [python]
def results(args):
    data = []
    for seed in [1000, 2000, 3000, 4000, 5000]:
        for hp in lengths :
            lei, fresh = get_new_type(args, args.dataset, seed, hp)
            if lei is not None:
                data.append(
                    {
                        "Dataset": datasets[args.dataset],
                        "Model": "lei",
                        "hp": hp,
                        "Macro F1": lei,
                    }
                )

            if fresh is not None:
                data.append(
                    {
                        "Dataset": datasets[args.dataset],
                        "Model": "fresh",
                        "hp": hp,
                        "Macro F1": fresh,
                    }
                )

    sns.set_context("talk")
    sns.set(style="white", rc={"lines.linewidth": 1.7}, font_scale=1.5)
    data = pd.DataFrame(data)

    breakpoint()

    f, ax = plt.subplots(1, 1, figsize=(5, 2.5))
    sns.pointplot(
        x="hp",
        y="Macro F1",
        hue="Model",
        data=data[data.Dataset == datasets[args.dataset]],
        ax=ax,
        dodge=True,
        join=True,
        hue_order=["lei", "fresh"],
        palette=["blue", "red"],
        markers=["o", "D"],
        ci="sd",
        estimator=np.median,
    )
    ax.set_xlabel("")
    ax.set_title(datasets[args.dataset])
    ax.legend_ = None

    plt.ylim(args.min_scale, args.max_scale)
    plt.legend().remove()
    sns.utils.despine()
    f.tight_layout()
    f.savefig(f"human_prob_{args.dataset}.pdf", bbox_inches="tight")
//  [python]
def plot_swarm_evenness(df, output, verbose=False):
    if verbose:
        sys.stderr.write(f"{bcolors.GREEN}Plotting swarmed evenness{bcolors.ENDC}\n")
    sns.violinplot(data=df, x='kmer', y='Evenness')
    sns.swarmplot(data=df, x='kmer', y='Evenness')
    sns.despine(offset=10, trim=True)
    plt.savefig(f"{output}.swarm.evenness.png")
    plt.clf()
//  [python]
def plot_swarm_evenness(df, output, verbose=False):
    if verbose:
        sys.stderr.write(f"{bcolors.GREEN}Plotting swarmed evenness{bcolors.ENDC}\n")
    sns.violinplot(data=df, x='kmer', y='Evenness')
    sns.swarmplot(data=df, x='kmer', y='Evenness')
    sns.utils.despine(offset=10, trim=True)
    plt.savefig(f"{output}.swarm.evenness.png")
    plt.clf()
//  [python]
def plot_shannon(df, output, verbose=False):
    if verbose:
        sys.stderr.write(f"{bcolors.GREEN}Plotting swarmed shannon{bcolors.ENDC}\n")
    sns.violinplot(data=df, x='kmer', y='Shannon')
    sns.swarmplot(data=df, x='kmer', y='Shannon')
    sns.despine(offset=10, trim=True)
    plt.savefig(f"{output}.shannon.png")
    plt.clf()
//  [python]
def plot_shannon(df, output, verbose=False):
    if verbose:
        sys.stderr.write(f"{bcolors.GREEN}Plotting swarmed shannon{bcolors.ENDC}\n")
    sns.violinplot(data=df, x='kmer', y='Shannon')
    sns.swarmplot(data=df, x='kmer', y='Shannon')
    sns.utils.despine(offset=10, trim=True)
    plt.savefig(f"{output}.shannon.png")
    plt.clf()
//  [python]
def plot_data(data, xaxis='Epoch', value="AverageEpRet", condition="Condition1", smooth=1, **kwargs):
    if smooth > 1:
        """
        smooth data with moving window average.
        that is,
            smoothed_y[t] = average(y[t-k], y[t-k+1], ..., y[t+k-1], y[t+k])
        where the "smooth" param is width of that window (2k+1)
        """
        y = np.ones(smooth)
        i=0
        for datum in data:
            # import ipdb
            # ipdb.set_trace()
            # y = np.ones(smooth)
            # if datum[condition][0] == 'SAC-FSP' or datum[condition][0] == 'SAC-raw':
            #     smooth_new = 195
            # else:
            #     smooth_new = smooth
            # y = np.ones(smooth_new)
            x = np.asarray(datum[value])
            z = np.ones(len(x))
            smoothed_x = np.convolve(x,y,'same') / np.convolve(z,y,'same')
            print('i={}, smoothed_x.size={},datum[value].size={}'.format(i,smoothed_x.size,datum[value].size))
            datum[value] = smoothed_x
            i=i+1

    if isinstance(data, list):
        data = pd.concat(data, ignore_index=True)
    # sns.set_context("poster", rc={"lines.linewidth": 3})
    sns.set(style="whitegrid", font_scale=1)
    sns.despine(top=True, right=True, left=False, bottom=False)
    # flatui = ["#1F77B3", "#FE7E0e", "#9267BB","#D52728", "#2C9F2C" , "#E277C1"] # blue, orange, purple, red, green, pink
    # flatui = ["#FF0000", "#185C8A", "#9267BB", "#FF8000", "#2C9F2C" , "#E277C1"] # red, blue, purple, orange, green, pink
    flatui = ["#9267BB", "#185C8A", "#FF0000", "#E277C1", "#2C9F2C" , "#FF8000"] # purple, blue, red, pink, green, orange FF8000 F9AB00  FB8D2B
    # sns.tsplot(data=data, time=xaxis, value=value, unit="Unit", condition=condition, ci='sd', **kwargs)
    with sns.color_palette(flatui):
        sns.lineplot(data=data, x=xaxis, y=value, hue=condition, errorbar='sd', legend=False, lw=2.5, **kwargs)
    """
    If you upgrade to any version of Seaborn greater than 0.8.1, switch from 
    tsplot to lineplot replacing L29 with:

        sns.lineplot(data=data, x=xaxis, y=value, hue=condition, ci='sd', **kwargs)

    Changes the colorscheme and the default legend style, though.
    """
    # plt.legend(loc='best').set_draggable(True)
    #plt.legend(loc='upper center', ncol=3, handlelength=1,
    #           borderaxespad=0., prop={'size': 13})

    """
    For the version of the legend used in the Spinning Up benchmarking page, 
    swap L38 with:

    plt.legend(loc='upper center', ncol=6, handlelength=1,
               mode="expand", borderaxespad=0., prop={'size': 13})
    """

    xscale = np.max(np.asarray(data[xaxis])) > 5e3
    if xscale:
        # Just some formatting niceness: x-axis scale in scientific notation if max x is large
        plt.ticklabel_format(style='sci', axis='x', scilimits=(0,0))

    plt.tight_layout(pad=0.5)
//  [python]
def plot_data(data, xaxis='Epoch', value="AverageEpRet", condition="Condition1", smooth=1, **kwargs):
    if smooth > 1:
        """
        smooth data with moving window average.
        that is,
            smoothed_y[t] = average(y[t-k], y[t-k+1], ..., y[t+k-1], y[t+k])
        where the "smooth" param is width of that window (2k+1)
        """
        y = np.ones(smooth)
        i=0
        for datum in data:
            # import ipdb
            # ipdb.set_trace()
            # y = np.ones(smooth)
            # if datum[condition][0] == 'SAC-FSP' or datum[condition][0] == 'SAC-raw':
            #     smooth_new = 195
            # else:
            #     smooth_new = smooth
            # y = np.ones(smooth_new)
            x = np.asarray(datum[value])
            z = np.ones(len(x))
            smoothed_x = np.convolve(x,y,'same') / np.convolve(z,y,'same')
            print('i={}, smoothed_x.size={},datum[value].size={}'.format(i,smoothed_x.size,datum[value].size))
            datum[value] = smoothed_x
            i=i+1

    if isinstance(data, list):
        data = pd.concat(data, ignore_index=True)
    # sns.set_context("poster", rc={"lines.linewidth": 3})
    sns.set(style="whitegrid", font_scale=1)
    sns.utils.despine(top=True, right=True, left=False, bottom=False)
    # flatui = ["#1F77B3", "#FE7E0e", "#9267BB","#D52728", "#2C9F2C" , "#E277C1"] # blue, orange, purple, red, green, pink
    # flatui = ["#FF0000", "#185C8A", "#9267BB", "#FF8000", "#2C9F2C" , "#E277C1"] # red, blue, purple, orange, green, pink
    flatui = ["#9267BB", "#185C8A", "#FF0000", "#E277C1", "#2C9F2C" , "#FF8000"] # purple, blue, red, pink, green, orange FF8000 F9AB00  FB8D2B
    # sns.tsplot(data=data, time=xaxis, value=value, unit="Unit", condition=condition, ci='sd', **kwargs)
    with sns.color_palette(flatui):
        sns.lineplot(data=data, x=xaxis, y=value, hue=condition, errorbar='sd', legend=False, lw=2.5, **kwargs)
    """
    If you upgrade to any version of Seaborn greater than 0.8.1, switch from 
    tsplot to lineplot replacing L29 with:

        sns.lineplot(data=data, x=xaxis, y=value, hue=condition, ci='sd', **kwargs)

    Changes the colorscheme and the default legend style, though.
    """
    # plt.legend(loc='best').set_draggable(True)
    #plt.legend(loc='upper center', ncol=3, handlelength=1,
    #           borderaxespad=0., prop={'size': 13})

    """
    For the version of the legend used in the Spinning Up benchmarking page, 
    swap L38 with:

    plt.legend(loc='upper center', ncol=6, handlelength=1,
               mode="expand", borderaxespad=0., prop={'size': 13})
    """

    xscale = np.max(np.asarray(data[xaxis])) > 5e3
    if xscale:
        # Just some formatting niceness: x-axis scale in scientific notation if max x is large
        plt.ticklabel_format(style='sci', axis='x', scilimits=(0,0))

    plt.tight_layout(pad=0.5)
//  [python]
def save_yearly_returns(returns, folder):
    plt.figure(figsize=(12,8))
    ax = plt.gca()
    despine()
    ax.yaxis.grid(linestyle=':')
    returns.index = returns.index.strftime('%Y')
    plt.bar(x=returns.index, height=returns.values)
    ax.set_title('Yearly Returns, %', fontweight='bold')
    ax.set_ylabel('%')
    plt.xticks(range(len(returns.index)), tuple(returns.index))
    ax.set_xlabel('Year')
    ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
    ax.xaxis.grid(False)
    save_plot(plt=plt, folder=folder, name='yearly_returns')
//  [python]
def save_yearly_returns(returns, folder):
    plt.figure(figsize=(12,8))
    ax = plt.gca()
    seaborn.utils.despine()
    ax.yaxis.grid(linestyle=':')
    returns.index = returns.index.strftime('%Y')
    plt.bar(x=returns.index, height=returns.values)
    ax.set_title('Yearly Returns, %', fontweight='bold')
    ax.set_ylabel('%')
    plt.xticks(range(len(returns.index)), tuple(returns.index))
    ax.set_xlabel('Year')
    ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
    ax.xaxis.grid(False)
    save_plot(plt=plt, folder=folder, name='yearly_returns')