Given a list of OTUs and a number of groups containing subsets of
    the OTU set, plot a presence/absence bar chart showing which species
    belong to which groups.
    
    :type otus: list
    :param otus: A list of OTU identifiers (names or otherwise) ordered
                 by greatest presence across the groups, i.e. those that
                 come first appear in all the groups, next come the OTUs
                 that appear in n-1 groups, etc...
    :type group_otus: OrderedDict
    :param group_otus: A dictionary of OTU identifiers (subset of otus)
                       keyed on group name (for display purposes) in
                       display order (bottom to top).
    :type group_colors: dict
    :param group_colors: Color assignment for each group.

def plot_overlaps(otus, group_otus, group_colors, 
                  out_fp, fig_size=None, title="",
                  filter_common=False):
    """
    Given a list of OTUs and a number of groups containing subsets of
    the OTU set, plot a presence/absence bar chart showing which species
    belong to which groups.
    
    :type otus: list
    :param otus: A list of OTU identifiers (names or otherwise) ordered
                 by greatest presence across the groups, i.e. those that
                 come first appear in all the groups, next come the OTUs
                 that appear in n-1 groups, etc...
    :type group_otus: OrderedDict
    :param group_otus: A dictionary of OTU identifiers (subset of otus)
                       keyed on group name (for display purposes) in
                       display order (bottom to top).
    :type group_colors: dict
    :param group_colors: Color assignment for each group.
    """
    def sort_order_group(sp):
        """
        Assign a score (for use with sorting) to each OTU based
        on the number of groups they occur in and the order
        within those groups (order priority as set by group_otus).
        """
        count = 0
        rank = 0
        in_prev = True
        max_penalty = len(group_otus)

        for i, grp in enumerate(group_otus):
            if sp in group_otus[grp]:
                count += 1
                if in_prev:
                    rank += 1
            else:
                rank -= max_penalty - i
                in_prev = False
        return count, rank


    if filter_common:
        otus = [otu for otu in otus if sort_order_group(otu)[0] < len(group_otus)]
    otus = sorted(otus, key=sort_order_group, reverse=True)

    #TODO: fill shared_table during the double loop below and add arg to enable output to file
    shared_table = [merge_dicts({grp: None for grp in group_otus},{"OTU": otu_id}) for otu_id in otus]
    
    fig, ax = plt.subplots(figsize=fig_size)
    ax.xaxis.set_major_locator(MaxNLocator(nbins=len(otus), integer=True))

    # rectangle prototype modified for each plot marker
    base = [(0,0),(0,0.5),(0,0.5),(0,0)]
    y_step = 1
    x_step = 2

    bars = []
    bar_colors = []

    for i, grp in enumerate(group_otus):

        for j, otu in enumerate(otus):
            if otu in group_otus[grp]:
                bars.append(translate(base, j*x_step+0.5, i*y_step))
                bar_colors.append(group_colors[grp])

    black = (0,0,0,1)

    collection = PolyCollection(
        verts=bars,
        facecolors = bar_colors,
        edgecolors = (black,),
        linewidths = (1,),
        transOffset = ax.transData,
        zorder=3
        )

    ax.add_collection(collection)

    # ax.legend([plt.Rectangle((0, 0), 1, 1, fc=color) for color in group_colors.values()],
    #               group_colors.keys(), loc="best")
    
    # Title
    axttl = ax.title
    axttl.set_position([.5, 1.05])
    ax.set_title(title, {"fontsize": fontsize*1.5, "fontweight": "bold"})
    
    plt.xticks(range(1, len(otus)*x_step, x_step), otus, rotation="vertical")
    plt.yticks([i-0.75 for i in range(1, len(group_otus)*y_step+1, y_step)], 
               group_otus.keys(), rotation="horizontal")

    ax.margins(0.05)
    ax.yaxis.set_visible(True)
    ax.set_xlim((0, len(otus)*x_step))

    # save or display result
    if out_fp:
        plt.savefig(out_fp, facecolors="0.9", edgecolor="none",
                    bbox_inches="tight", pad_inches=0.1)
    else:
        plt.show()