def plot_graphs(cell_line, lineage_num, num_plots=5, parA_heatmap=None, save=True, labels=None, um=False, plot_kwargs=None):
    lineage = track.Lineage()
    if save:
        fig = plt.figure(figsize=(20, 10))
        gs = matplotlib.gridspec.GridSpec(2, 3)
        fig.patch.set_alpha(0)

    spots_ParA = []
    traces_ParA = []
    L = []
    T = shared.get_timings()
    for cell in cell_line:
        spots_ParA.append(cell.ParA)
        traces_ParA.append(cell.parA_fluorescence_smoothed[::-1])
        if um:
            L.append(cell.length[0][0] * PX)
        else:
            L.append(cell.length[0][0])
    L = np.array(L)

    traces_ParA = np.concatenate(traces_ParA)
    max_parA_intensity = traces_ParA.max()

    start = cell_line[0].frame - 1
    end = cell_line[-1].frame - 1
    t = np.array(T[start:end + 1])

    if save:
        parA_heatmap = fig.add_subplot(gs[0, 0])
        _despine(parA_heatmap)
    # use Rectangles to generate a heatmap
    i = 0
    cmapper = plt.cm.get_cmap("afmhot")
    for cell in cell_line:
        trace = cell.parA_fluorescence_smoothed
        if um:
            l = cell.length[0][0] * PX
        else:
            l = cell.length[0][0]
        x0 = t[i] - 8
        y0 = -(l / 2)
        increment = l / len(trace)
        colours = cmapper(trace / max_parA_intensity)
        i2 = 0
        for _t in trace:
            if _t < 0:
                _t = 0
            r = matplotlib.patches.Rectangle(
                (x0, y0),
                width=15,
                height=increment,
                facecolor=colours[i2],
                edgecolor="none",
            )
            parA_heatmap.add_patch(r)
            y0 += increment
            i2 += 1
        i += 1

    if save:
        parA_heatmap.set_ylabel(r"Distance from mid-cell (px)")
        parA_heatmap.set_xlabel(r"Time (min)")
        parA_heatmap.set_title("ParA")

    poledict = poles.PoleAssign(lineage.frames).assign_poles()
    if poledict[cell_line[0].id] is None:
        parA_heatmap.plot(t, L / 2, "r-", lw=2)
        parA_heatmap.plot(t, -(L / 2), "r-", lw=2)
    else:
        parA_heatmap.plot(t, L / 2, "k-", lw=2)
        parA_heatmap.plot(t, -(L / 2), "k-", lw=2)

    parAs = {}
    i = 0
    for s in spots_ParA:
        midcell = s[2] / 2
        spot = s[0] - midcell
        parAs[t[i]] = spot
        i += 1
    parAs = np.array(sorted(parAs.items()))

    if num_plots >= 2:
        parA_heatmap.plot(
            parAs[:, 0], parAs[:, 1],
            lw=2, marker=".", mec="k", ms=10
        )

    decorate_daughters(cell_line, lineage, parA_heatmap, labels=labels, um=um)
    parA_heatmap.patch.set_alpha(0)

    if num_plots >= 3:
        ax_parA = fig.add_subplot(gs[1, 0])
        _despine(ax_parA)
        ax_parA.set_title("ParA maximum")
        ax_parA.plot(
            parAs[:, 0], (L / 2) - parAs[:, 1],
            marker=".", lw=2, mec="k", ms=10,
            label="Distance from top pole"
        )
        ax_parA.plot(
            parAs[:, 0], (L / 2) + parAs[:, 1],
            marker=".", lw=2, mec="k", ms=10,
            label="Distance from bottom pole"
        )
        ax_parA.set_xlabel(r"Time (min)")
        ax_parA.set_ylabel(r"Distance (px)")
        ax_parA.patch.set_alpha(0)

    if num_plots >= 2:
        parB_midcell = fig.add_subplot(gs[0, 1])
        _despine(parB_midcell)
        parB_midcell.set_title("ParB")
        parB_midcell.plot(t, L / 2, "k-", lw=2, label="Cell poles")
        parB_midcell.plot(t, -(L / 2), "k-", lw=2)

    spots_ParB = shared.get_parB_path(cell_line, T, lineage_num)
    spotnum = 1
    for x in spots_ParB:
        s = x.spots(False)
        if hasattr(x, "split_parent") and x.split_parent:
            for y in spots_ParB:
                if y.spot_ids[-1] == x.split_parent:
                    textra = y.timing[-1:]
                    timings = np.concatenate([textra, s["timing"]])
                    posextra = np.array(y.position[-1:])
                    if um:
                        positions = np.concatenate([posextra * PX, s["position"] * PX])
                    else:
                        positions = np.concatenate([posextra, s["position"]])
                    break
        else:
            timings = s["timing"]
            if um:
                positions = s["position"] * PX
            else:
                positions = s["position"]

        if num_plots >= 2:
            ax_target = parB_midcell
            label = "Spot {0}".format(spotnum)
        else:
            ax_target = parA_heatmap
            label = "ParB"

        if plot_kwargs:
            ax_target.plot(
                timings, positions, **plot_kwargs
            )
        else:
#            ax_target.plot(
#                timings, positions,
#                lw=2,
#                marker=".",
#                markeredgecolor="k",
#                ms=10,
#                label=label,
#                color=colour,
#            )
            ax_target.plot(
                timings, positions,
                lw=2,
                marker=".",
                markeredgecolor="k",
                ms=10,
                label=label,
                color="k",
                path_effects=[
                    matplotlib.patheffects.Stroke(
                        linewidth=2, foreground=(0.7, 0.7, 0.7)
                    )
                ],
            )

        dparA = []
        for spot in s:
            parApos = parAs[np.where(parAs[:, 0] == spot[0])][0, 1]
            dpA = spot[1] - parApos
            dparA.append(dpA)

        x.parA_d = dparA
        x.parA_dmean = np.mean(dparA)
        x.parA_dsem = np.std(dparA) / np.sqrt(len(dparA))
        x.spotnum = spotnum
        x.intensity_mean = s["intensity"].mean()

        spotnum += 1

    if num_plots >= 2:
        lines = parB_midcell.lines[::-1]
        for l in lines:
            parB_midcell.lines.remove(l)
            parB_midcell.add_line(l)

        parB_midcell.set_ylabel(r"Distance from mid-cell (px)")
        parB_midcell.set_xlabel(r"Time (min)")

        decorate_daughters(cell_line, lineage, parB_midcell, pad=5, labels=labels, um=um)

        parB_midcell.legend(bbox_to_anchor=(1.35, 1))
        parB_midcell.patch.set_alpha(0)
    else:
        if save:
            parA_heatmap.legend(
                [parA_heatmap.lines[-1]], [parA_heatmap.lines[-1].get_label()],
                bbox_to_anchor=(1.2, 1)
            )

    if num_plots >= 4:
        filtered = [x for x in spots_ParB if len(x) > 4]
        if len(filtered) > 0:
            ax_parB_closest = fig.add_subplot(gs[1, 1], sharex=ax_parA, sharey=ax_parA)
            dmin = min(
                filtered,
                key=lambda x: np.abs(x.parA_dmean)
            )
            ax_parB_closest.set_title("ParB spot {0} (dmin)".format(dmin.spotnum))
            _despine(ax_parB_closest)
            s = dmin.spots(False)
            dpol_t = (dmin.len() / 2) - s["position"]
            dpol_b = (dmin.len() / 2) + s["position"]

            ax_parB_closest.plot(
                s["timing"], dpol_t,
                marker=".", lw=2, mec="k", ms=10,
                label="Distance from top pole"
            )
            ax_parB_closest.plot(
                s["timing"], dpol_b,
                marker=".", lw=2, mec="k", ms=10,
                label="Distance from bottom pole"
            )
            ax_parB_closest.plot(
                s["timing"], dmin.parA_d,
                marker=".", lw=2, ms=10,
                label="Distance from ParA focus"
            )
            ax_parB_closest.plot(
                ax_parB_closest.get_xlim(),
                [0, 0],
                "k--"
            )
            ax_parB_closest.patch.set_alpha(0)

            if num_plots >= 5:
                imax = max(filtered, key=lambda x: x.intensity_mean)
                if imax.id != dmin.id:
                    ax_parB_highest = fig.add_subplot(gs[1, 2], sharex=ax_parB_closest, sharey=ax_parA)
                    s = imax.spots(False)
                    dpol_t = (imax.len() / 2) - s["position"]
                    dpol_b = (imax.len() / 2) + s["position"]
                    ax_parB_highest.plot(s["timing"], dpol_t, marker=".", lw=2, mec="k", ms=10, label="Distance from top pole")
                    ax_parB_highest.plot(s["timing"], dpol_b, marker=".", lw=2, mec="k", ms=10, label="Distance from bottom pole")
                    ax_parB_highest.plot(s["timing"], imax.parA_d, marker=".", lw=2, mec="k", ms=10, label="Distance from ParA focus")

                    ax_parB_highest.plot(ax_parB_highest.get_xlim(), [0, 0], "k--")

                    _despine(ax_parB_highest)
                    ax_parB_highest.set_title("ParB Spot {0} (imax)".format(imax.spotnum))
                    ax_parB_highest.set_ylabel(r"Distance (px)")
                    ax_parB_highest.set_xlabel("Time (min)")
                    ax_parB_highest.patch.set_alpha(0)
                    ax_parB_highest.legend(bbox_to_anchor=(0.8, 1.35))
                else:
                    ax_parB_closest.legend(bbox_to_anchor=(1.65, 1))
            else:
                ax_parB_closest.legend(bbox_to_anchor=(1.65, 1))
        else:
            ax_parA.legend(bbox_to_anchor=(1.65, 1))

    if save:
        plt.tight_layout()
        fn = "data/data-lineage{0:02d}.pdf".format(lineage_num)
        plt.savefig(fn)
        print("Saved data file to {0}".format(fn))
def plot_graphs_parB_only(cell_line, lineage_num, ax_parB=None, save=True, labels=None, um=False):
    if um:
        L = np.array([x.length[0][0] * PX for x in cell_line])
    else:
        L = np.array([x.length[0][0] for x in cell_line])
    T = shared.get_timings()
    t = np.array(T[cell_line[0].frame - 1:cell_line[-1].frame])

    lineage = track.Lineage()

    if not ax_parB:
        fig = plt.figure(figsize=(20 / 3, 5))
        ax_parB = fig.add_subplot(111)
        _despine(ax_parB)
        ax_parB.set_title("ParB")
        ax_parB.set_ylabel(r"Distance from mid-cell (px)")
        ax_parB.set_xlabel(r"Time (min)")

    poledict = poles.PoleAssign(lineage.frames).assign_poles()
    if poledict[cell_line[0].id] is None:
        ax_parB.plot(t, L / 2, "r-", lw=2, label="Cell poles")
        ax_parB.plot(t, -(L / 2), "r-", lw=2)
    else:
        ax_parB.plot(t, L / 2, "k-", lw=2, label="Cell poles")
        ax_parB.plot(t, -(L / 2), "k-", lw=2)

    spots_ParB = shared.get_parB_path(cell_line, T, lineage_num)
    spotnum = 1
    colourwheel = sns.color_palette(n_colors=len(spots_ParB))
    for x in spots_ParB:
        colour = colourwheel[spotnum - 1]
        s = x.spots(False)
        if hasattr(x, "split_parent") and x.split_parent:
            for y in spots_ParB:
                if y.spot_ids[-1] == x.split_parent:
                    textra = y.timing[-1:]
                    timings = np.concatenate([textra, s["timing"]])
                    posextra = np.array(y.position[-1:])
                    if um:
                        positions = np.concatenate([posextra * PX, s["position"] * PX])
                    else:
                        positions = np.concatenate([posextra, s["position"]])
                    break
        else:
            timings = s["timing"]
            if um:
                positions = s["position"] * PX
            else:
                positions = s["position"]

        ax_parB.plot(
            timings, positions,
            lw=2, marker=".",
            mec="k", ms=10,
            label="Spot {0}".format(spotnum),
            color=colour
        )
        spotnum += 1

    lines = ax_parB.lines[::-1]
    for l in lines:
        ax_parB.lines.remove(l)
        ax_parB.add_line(l)

    decorate_daughters(cell_line, lineage, ax_parB, pad=5, labels=labels, um=um)

    if save:
        ax_parB.legend(bbox_to_anchor=(1.35, 1))
        ax_parB.patch.set_alpha(0)

        plt.tight_layout()
        fn = "data/data-lineage{0:02d}.pdf".format(lineage_num)
        plt.savefig(fn)
        print("Saved data file to {0}".format(fn))
        plt.close()