def animate(i):
        print(i)
        try:
            cent, img, msk = next(data)
            image_ax.set_data(img)
            mask_ax.set_data(msk)
            x_coord, y_coord = parse_centroid_coords(cent)
            if len(cent) > 1:
                single_droplet_1.set_data([], [])
                single_droplet_2.set_data([], [])
                multi_droplet_1.set_data(x_coord, y_coord)
                multi_droplet_2.set_data(x_coord, y_coord)
            elif len(cent) == 1:
                single_droplet_1.set_data(x_coord, y_coord)
                single_droplet_2.set_data(x_coord, y_coord)
                multi_droplet_1.set_data([], [])
                multi_droplet_2.set_data([], [])
            else:
                single_droplet_1.set_data([], [])
                single_droplet_2.set_data([], [])
                multi_droplet_1.set_data([], [])
                multi_droplet_2.set_data([], [])
            plt.title(f'Frame {i}')
            return image_ax, mask_ax, single_droplet_1, multi_droplet_1, single_droplet_2, multi_droplet_2,

        except StopIteration as error:
            print(error)
def animate_centroids(save=False):
    '''
    Saves animation of original image with markers for the centroids of each droplet.

    Kwargs:
    save {bool} -- wether to save the animation as a .mp4 or show it using plt.show().
    '''
    def centroid_img_generator():
        for cent, image in zip(CENTROIDS, IMAGES):
            yield cent, image
    data = centroid_img_generator()
    cent, img = next(data)
    x_coord, y_coord = parse_centroid_coords(cent)
    fig = plt.figure()
    with sns.axes_style('dark'):
        axes = plt.axes()
    image_ax = axes.imshow(img)
    if len(cent) > 1:
        single_droplet, = axes.plot([], [], 'k.')
        multi_droplet, = axes.plot(x_coord, y_coord, 'rx')
    elif len(cent) == 1:
        single_droplet, = axes.plot(x_coord, y_coord, 'k.')
        multi_droplet, = axes.plot([], [], 'rx')
    else:
        single_droplet, = axes.plot([], [], 'k.')
        multi_droplet, = axes.plot([], [], 'rx')
    plt.show()

    def animate(i):
        try:
            cent, img = next(data)
            image_ax.set_data(img)
            x_coord, y_coord = parse_centroid_coords(cent)
            if len(cent) > 1:
                single_droplet.set_data([], [])
                multi_droplet.set_data(x_coord, y_coord)
            elif len(cent) == 1:
                single_droplet.set_data(x_coord, y_coord)
                multi_droplet.set_data([], [])
            else:
                single_droplet.set_data([], [])
                multi_droplet.set_data([], [])
            plt.title(f'Frame #{i}')
            return image_ax, single_droplet, multi_droplet,
        except StopIteration as error:
            print(error)

    ani = FuncAnimation(fig, animate, save_count=N_FRAMES-1)
    if save:
        ani.save(os.path.join('Output', 'Videos',
                              f'centroids_{DATASET.lower()}.mp4'), writer=WRITER)
    else:
        plt.show()
 def animate(i):
     try:
         cent, img = next(data)
         image_ax.set_data(img)
         x_coord, y_coord = parse_centroid_coords(cent)
         if len(cent) > 1:
             single_droplet.set_data([], [])
             multi_droplet.set_data(x_coord, y_coord)
         elif len(cent) == 1:
             single_droplet.set_data(x_coord, y_coord)
             multi_droplet.set_data([], [])
         else:
             single_droplet.set_data([], [])
             multi_droplet.set_data([], [])
         plt.title(f'Frame #{i}')
         return image_ax, single_droplet, multi_droplet,
     except StopIteration as error:
         print(error)
def plot_centroids(num, save=False):
    '''
    Plots a specific frame of a video and overlays the predicted centroid.

    Args:
    num {int} -- mumber of the frame to plot.

    Kwargs:
    save {bool} -- wether to save the plot as .pgf file or to show using plt.show().
    '''
    cent = CENTROIDS[num]
    x_coord, y_coord = parse_centroid_coords(cent)
    image = Image.fromarray(IMAGES[num])
    mask = Image.fromarray(MASKS[num])
    img_mask = get_concat_h(image, mask)
    with sns.axes_style('dark'):
        fig, axes = plt.subplots(1, 1, figsize=set_size(
            width_pt=440, aspect_ratio=.42))
    axes.set_xticks([])
    axes.set_yticks([])

    axes.set_title(f'Frame {num}')
    axes.imshow(img_mask)

    if len(cent) > 1:
        axes.scatter(x_coord, y_coord, s=10, marker='x', color='r')
        axes.scatter([x+IMAGES.shape[2] for x in x_coord],
                     y_coord, s=10, marker='x', color='r')

    elif len(cent) == 1:
        axes.scatter(x_coord, y_coord, s=10, marker='.', color='k')
        axes.scatter([x+IMAGES.shape[2] for x in x_coord],
                     y_coord, s=10, marker='.', color='k')

    if save:
        os.makedirs(os.path.join('Output', 'Plots',
                                 'centroid_samples'), exist_ok=True)
        fig.tight_layout()
        latex_plot_config()
        fig.savefig(os.path.join('Output', 'Plots',
                                 'centroid_samples', f'{DATASET.lower()}_{num}.pgf'))
    else:
        plt.show()
    def animate(i):
        print(i)
        if i != 0 and i % width == 0:
            ax0.clear()
            ax0.xaxis.tick_top()
            ax0.set_xlabel('Frame')
            ax0.xaxis.set_label_position('top')
            ax0.set_ylabel(r'Area [$mm^2$]')
        areas, cent, img, mask = next(data)
        if len(areas) == 0:
            ax0.plot(i, 0, 'bo')
        else:
            for area in areas:
                if len(areas) > 1:
                    ax0.plot(i, area, 'rx')
                elif len(areas) == 1:
                    ax0.plot(i, area, 'k.')
        image_ax.set_data(img)
        mask_ax.set_data(mask)

        x_coord, y_coord = parse_centroid_coords(cent)
        if len(cent) > 1:
            single_droplet_1.set_data([], [])
            single_droplet_2.set_data([], [])
            multi_droplet_1.set_data(x_coord, y_coord)
            multi_droplet_2.set_data(x_coord, y_coord)
        elif len(cent) == 1:
            single_droplet_1.set_data(x_coord, y_coord)
            single_droplet_2.set_data(x_coord, y_coord)
            multi_droplet_1.set_data([], [])
            multi_droplet_2.set_data([], [])
        else:
            single_droplet_1.set_data([], [])
            single_droplet_2.set_data([], [])
            multi_droplet_1.set_data([], [])
            multi_droplet_2.set_data([], [])
        if i in peaks:
            ax0.axvline(x=i, color='k', alpha=0.4, linestyle='--')
        ax1.set_title(f'Frame {i}')
        return image_ax, mask_ax, single_droplet_1, multi_droplet_1, single_droplet_2, multi_droplet_2,
def animate_centroids_with_masks(save=False):
    '''
    Saves animation of original image and mask with markers for the centroids of each droplet.

    Kwargs:
    save {bool} -- wether to save the animation as a .mp4 or to show it with plt.show().
    '''
    def centroid_mask_img_generator():
        for cent, image, mask in zip(CENTROIDS, IMAGES, MASKS):
            yield cent, image, mask
    data = centroid_mask_img_generator()
    cent, img, msk = next(data)
    x_coord, y_coord = parse_centroid_coords(cent)
    with sns.axes_style('dark'):
        fig, axes = plt.subplots(1, 2)
    image_ax = axes[0].imshow(img)
    mask_ax = axes[1].imshow(msk)
    if len(cent) > 1:
        single_droplet_1, = axes[0].plot([], [], 'k.')
        multi_droplet_1, = axes[0].plot(x_coord, y_coord, 'rx')

        single_droplet_2, = axes[1].plot([], [], 'k.')
        multi_droplet_2, = axes[1].plot(x_coord, y_coord, 'rx')
    elif len(cent) == 1:
        single_droplet_1, = axes[0].plot(x_coord, y_coord, 'k.')
        multi_droplet_1, = axes[0].plot([], [], 'rx')

        single_droplet_2, = axes[1].plot(x_coord, y_coord, 'k.')
        multi_droplet_2, = axes[1].plot([], [], 'rx')

    else:
        single_droplet_1, = axes[0].plot([], [], 'k.')
        multi_droplet_1, = axes[0].plot([], [], 'rx')

        single_droplet_2, = axes[1].plot([], [], 'k.')
        multi_droplet_2, = axes[1].plot([], [], 'rx')

    def animate(i):
        print(i)
        try:
            cent, img, msk = next(data)
            image_ax.set_data(img)
            mask_ax.set_data(msk)
            x_coord, y_coord = parse_centroid_coords(cent)
            if len(cent) > 1:
                single_droplet_1.set_data([], [])
                single_droplet_2.set_data([], [])
                multi_droplet_1.set_data(x_coord, y_coord)
                multi_droplet_2.set_data(x_coord, y_coord)
            elif len(cent) == 1:
                single_droplet_1.set_data(x_coord, y_coord)
                single_droplet_2.set_data(x_coord, y_coord)
                multi_droplet_1.set_data([], [])
                multi_droplet_2.set_data([], [])
            else:
                single_droplet_1.set_data([], [])
                single_droplet_2.set_data([], [])
                multi_droplet_1.set_data([], [])
                multi_droplet_2.set_data([], [])
            plt.title(f'Frame {i}')
            return image_ax, mask_ax, single_droplet_1, multi_droplet_1, single_droplet_2, multi_droplet_2,

        except StopIteration as error:
            print(error)

    ani = FuncAnimation(fig, animate, save_count=N_FRAMES-1)
    if save:
        ani.save(os.path.join('Output', 'Videos',
                              f'centroid_with_masks_{DATASET.lower()}.mp4'), writer=WRITER)
    else:
        plt.show()
def animate_areas_with_masks(width, func, save=False):
    '''
    Same as animate_areas() but includes the corresponding masks. Also displays the centroids.

    Args:
    width {int} -- length of the time frames, e.g. a signal with length 100 animated with width 10 will refresh the animation
                   every 10 frames.

    Kwargs:
    save {bool} -- wether to save the animation as a .mp4 file or show it using plt.show().
    '''
    def areas_centroid_img_mask_generator():
        for i, cent_img_mask in enumerate(zip(CENTROIDS, IMAGES, MASKS)):
            yield AREAS[i], *cent_img_mask
    data = areas_centroid_img_mask_generator()
    areas, cent, img, mask = next(data)
    x_coord, y_coord = parse_centroid_coords(cent)
    fig = plt.figure()
    grid_spec = fig.add_gridspec(2, 2)
    ax0 = fig.add_subplot(grid_spec[0, :])
    ax0.xaxis.tick_top()
    ax0.set_xlabel('Frame')
    ax0.xaxis.set_label_position('top')
    ax0.set_ylabel(r'Area [$mm^2$]')

    with sns.axes_style('dark'):
        ax1 = fig.add_subplot(grid_spec[1, 0])
        ax2 = fig.add_subplot(grid_spec[1, 1])
    ax1.set_xticks([])
    ax1.set_yticks([])
    ax2.set_xticks([])
    ax2.set_yticks([])
    if len(areas) == 0:
        ax0.plot(0, 0, 'bo')
    else:
        for area in areas:
            if len(areas) > 1:
                ax0.plot(0, area, 'rx')
            elif len(areas) == 1:
                ax0.plot(0, area, 'k.')

    image_ax = ax1.imshow(img)
    mask_ax = ax2.imshow(mask)
    ax0.set_ylim([0, max(max(AREAS))])

    if len(cent) > 1:
        single_droplet_1, = ax1.plot([], [], 'k.')
        multi_droplet_1, = ax1.plot(x_coord, y_coord, 'rx')

        single_droplet_2, = ax2.plot([], [], 'k.')
        multi_droplet_2, = ax2.plot(x_coord, y_coord, 'rx')
    elif len(cent) == 1:
        single_droplet_1, = ax1.plot(x_coord, y_coord, 'k.')
        multi_droplet_1, = ax1.plot([], [], 'rx')

        single_droplet_2, = ax2.plot(x_coord, y_coord, 'k.')
        multi_droplet_2, = ax2.plot([], [], 'rx')

    else:
        single_droplet_1, = ax1.plot([], [], 'k.')
        multi_droplet_1, = ax1.plot([], [], 'rx')

        single_droplet_2, = ax2.plot([], [], 'k.')
        multi_droplet_2, = ax2.plot([], [], 'rx')
    original_area = []
    for areas in AREAS:
        if len(areas) > 0:
            original_area.append(func(areas))
        else:
            original_area.append(0)
    # globular
    if DATASET.lower() == 'globular':
        smooth_area = smooth_signal(np.array(original_area), 41)
        peaks = find_peaks(-smooth_area, height=-5, prominence=2)[0]
    # spray
    if DATASET.lower() == 'spray':
        smooth_area = smooth_signal(np.array(original_area), 7)
        peaks = find_peaks(smooth_area)[0]

    def animate(i):
        print(i)
        if i != 0 and i % width == 0:
            ax0.clear()
            ax0.xaxis.tick_top()
            ax0.set_xlabel('Frame')
            ax0.xaxis.set_label_position('top')
            ax0.set_ylabel(r'Area [$mm^2$]')
        areas, cent, img, mask = next(data)
        if len(areas) == 0:
            ax0.plot(i, 0, 'bo')
        else:
            for area in areas:
                if len(areas) > 1:
                    ax0.plot(i, area, 'rx')
                elif len(areas) == 1:
                    ax0.plot(i, area, 'k.')
        image_ax.set_data(img)
        mask_ax.set_data(mask)

        x_coord, y_coord = parse_centroid_coords(cent)
        if len(cent) > 1:
            single_droplet_1.set_data([], [])
            single_droplet_2.set_data([], [])
            multi_droplet_1.set_data(x_coord, y_coord)
            multi_droplet_2.set_data(x_coord, y_coord)
        elif len(cent) == 1:
            single_droplet_1.set_data(x_coord, y_coord)
            single_droplet_2.set_data(x_coord, y_coord)
            multi_droplet_1.set_data([], [])
            multi_droplet_2.set_data([], [])
        else:
            single_droplet_1.set_data([], [])
            single_droplet_2.set_data([], [])
            multi_droplet_1.set_data([], [])
            multi_droplet_2.set_data([], [])
        if i in peaks:
            ax0.axvline(x=i, color='k', alpha=0.4, linestyle='--')
        ax1.set_title(f'Frame {i}')
        return image_ax, mask_ax, single_droplet_1, multi_droplet_1, single_droplet_2, multi_droplet_2,

    ani = FuncAnimation(fig, animate, save_count=N_FRAMES-1)
    if save:
        ani.save(os.path.join('Output', 'Videos',
                              f'areas_with_masks_{DATASET.lower()}.mp4'), writer=WRITER)
    else:
        plt.show()