Exemple #1
0
def img_from_tex(tex, font_size=20):

    figure = matplotlib.figure.Figure(None, facecolor='white')
    #canvas = matplotlib.backends.backend_wxagg.FigureCanvasWxAgg(None, -1, figure)
    canvas = matplotlib.backends.backend_wxagg.FigureCanvasAgg(figure)

    font_size = font_size

    tex = "${0}$".format(tex)

    figure.clear()
    figure.text(0.05, 0.5, tex, size=font_size)
    canvas.draw()

    filename = 'equ.png'

    figure.savefig(filename, dpi=600)

    img = Image.open(filename)

    imginv = ImageChops.invert(img.convert('L'))

    box = imginv.getbbox()
    img = img.crop(box)

    img = ImageOps.expand(img, border=10, fill=(255, 255, 255))

    img.save(filename)

    return img
Exemple #2
0
def tex2img(tex, filename="equ.png", font_size=20):

    font_size = 20

    figure = matplotlib.figure.Figure(None, facecolor=(0, 0, 0, 0))
    canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(figure)

    font_size = font_size

    tex = "${0}$".format(tex)

    figure.clear()
    figure.text(0.05, 0.5, tex, size=font_size)

    canvas.draw()

    png = "equ.png"

    figure.savefig(png, transparent=True, dpi=300, format="png")

    img = Image.open(png)

    imginv = ImageChops.invert(img.convert('L'))

    box = imginv.getbbox()

    img = img.crop(box)

    img = ImageOps.expand(img, border=10, fill=(255, 255, 255, 0))

    img.save(png, format="png")

    return img
 def deleteLater(self):
     """
     Deletes this tab (later).
     """
     for figure in self._figures:
         figure.clear()
     for axes in self._axes:
         axes.cla()
     del (self._figures, self._axes)
     gc.collect()
     super(WcpTab, self).deleteLater()
Exemple #4
0
def draw_smiley(pos_x: float, pos_y: float,
                fade_in_frames: int) -> Generator[Image.Image, None, None]:
    """
    Generator method for rendering an emoji style smiley face
    :param pos_x: x axes offset for the center of the smiley face
    :param pos_y: y axes offset for the center of the smiley face
    :param fade_in_frames: Number of frames to fade in the smiley face
    :return: generator to produce the PIL Image frames
    """
    figure = plt.figure(figsize=(19.2, 10.8))
    fade_in_alpha = np.power(np.linspace(0, 1, fade_in_frames), 2)
    for alpha in fade_in_alpha:
        figure.clear()
        ax = figure.add_axes([0, 0, 1, 1])
        ax.set_xlim(-960, 960)
        ax.set_ylim(-540, 540)
        face_circle = Circle((pos_x, pos_y), 200, color="yellow", alpha=alpha)
        face_circle.set_facecolor("yellow")
        ax.add_patch(face_circle)
        left_eye_circle = Circle((pos_x - 80, pos_y + 50),
                                 50,
                                 color="black",
                                 alpha=alpha)
        ax.add_patch(left_eye_circle)
        right_eye_circle = Circle((pos_x + 80, pos_y + 50),
                                  50,
                                  color="black",
                                  alpha=alpha)
        ax.add_patch(right_eye_circle)
        smile = Wedge((pos_x, pos_y - 50),
                      100,
                      180,
                      0,
                      color="black",
                      alpha=alpha)
        ax.add_patch(smile)
        figure.set_facecolor("None")
        ax.axis("off")
        im = convert_plot_to_image(figure)
        yield im

    while True:
        yield im
Exemple #5
0
def main():
    """
    Entry point for rendering the plot
    """
    anim_file_path = Path("./test.mp4")
    figure = plt.figure(figsize=(19.2, 10.8))

    file_writer = FFMpegFileWriter(fps=FRAME_RATE)
    with file_writer.saving(figure, anim_file_path, dpi=100):
        intro_text = Scene(
            0,
            169,
            1,
            draw_text(
                sentence="I've seen things you people wouldn't believe",
                text_pos_list=[16, 44],
                alpha_transitions=60,
                persist_frames=0,
                fade_out_frames=24,
                font_size=48,
                left_offset=0.12,
                bottom_offset=0.0,
            ),
        )
        eye = Scene(
            intro_text.start_frame,
            intro_text.end_frame,
            0,
            draw_eye(axes_dims=[0, 0.22, 1.0, 0.8],
                     persist_frames=24,
                     fade_out_frames=24),
        )
        heatmap = Scene(
            intro_text.end_frame - 47,
            intro_text.end_frame + 145,
            2,
            draw_fire_automata(
                axes_dims=[0.2, 0.35, 0.6, 0.6],
                fade_in_frames=24,
                update_frames=144,
                fade_out_frames=24,
            ),
        )
        gaussian = Scene(
            intro_text.end_frame + 1,
            intro_text.end_frame + 145,
            1,
            draw_gaussian(
                axes_dims=[0.05, 0.1, 0.9, 0.25],
                fade_in_frames=24,
                update_frames=72,
                persist_frames=24,
                fade_out_frames=24,
            ),
        )
        heatmaps_text = Scene(
            145,
            313,
            1,
            draw_text(
                sentence="Heat maps on fire off the shoulder of a Gaussian",
                text_pos_list=[17, 48],
                alpha_transitions=60,
                persist_frames=24,
                fade_out_frames=24,
                font_size=48,
                left_offset=0.08,
                bottom_offset=0.0,
            ),
        )
        learning_curve = Scene(
            heatmaps_text.end_frame + 1,
            heatmaps_text.end_frame + 277,
            1,
            draw_learning_curve(
                topo_axes_dims=[0.01, 0.15, 0.5, 0.8],
                learning_curve_axes_dims=[0.54, 0.15, 0.44, 0.8],
                fade_in_frames=24,
                update_frames=156,
                persist_frames=72,
                fade_out_frames=24,
            ),
        )
        residuals_text = Scene(
            heatmaps_text.end_frame + 1,
            heatmaps_text.end_frame + 277,
            2,
            draw_text(
                sentence=
                "I watched residuals diminish down the arc of ten thousand weights",
                text_pos_list=[10, 41, 65],
                alpha_transitions=60,
                persist_frames=72,
                fade_out_frames=24,
                font_size=40,
                left_offset=0.015,
                bottom_offset=0.0,
            ),
        )
        fade_text_1 = Scene(
            residuals_text.end_frame + 1,
            residuals_text.end_frame + 193,
            2,
            draw_text(
                sentence="All these visuals",
                text_pos_list=[17],
                alpha_transitions=60,
                persist_frames=84,
                fade_out_frames=48,
                font_size=100,
                left_offset=0.2,
                bottom_offset=0.53,
            ),
        )
        fade_text_2 = Scene(
            residuals_text.end_frame + 60,
            residuals_text.end_frame + 193,
            2,
            draw_text(
                sentence="will fade in time",
                text_pos_list=[17],
                alpha_transitions=60,
                persist_frames=24,
                fade_out_frames=48,
                font_size=100,
                left_offset=0.2,
                bottom_offset=0.37,
            ),
        )
        terrain = Scene(
            fade_text_2.end_frame + 49,
            fade_text_2.end_frame + 169,
            1,
            draw_terrain(
                axes_dims=[0.05, 0.2, 0.9, 0.8],
                fade_in_frames=24,
                update_frames=72,
                fade_out_frames=24,
                frame_jiggle=0.01,
            ),
        )
        tears_text = Scene(
            fade_text_2.end_frame + 1,
            fade_text_2.end_frame + 169,
            2,
            draw_text(
                sentence="Like tears in terrain",
                text_pos_list=[11, 21],
                alpha_transitions=48,
                persist_frames=48,
                fade_out_frames=24,
                font_size=60,
                left_offset=0.3,
                bottom_offset=0,
            ),
        )
        pi_text_1 = Scene(
            tears_text.end_frame + 1,
            tears_text.end_frame + 217,
            2,
            draw_text(
                sentence="Time to pi",
                text_pos_list=[4, 10],
                alpha_transitions=72,
                persist_frames=72,
                fade_out_frames=0,
                font_size=80,
                left_offset=0.08,
                bottom_offset=0.8,
            ),
        )
        pi_text_2 = Scene(
            tears_text.end_frame + 169,
            tears_text.end_frame + 217,
            1,
            draw_text(
                sentence="Time to pip install matplotlib",
                text_pos_list=[30],
                alpha_transitions=24,
                persist_frames=100,
                fade_out_frames=0,
                font_size=80,
                left_offset=0.08,
                bottom_offset=0.8,
            ),
        )
        smiley = Scene(
            tears_text.end_frame + 169,
            tears_text.end_frame + 217,
            2,
            draw_smiley(fade_in_frames=24, pos_x=0, pos_y=0),
        )
        active_scenes_list: List[Scene] = [
            intro_text,
            eye,
            heatmap,
            gaussian,
            heatmaps_text,
            learning_curve,
            residuals_text,
            fade_text_1,
            fade_text_2,
            terrain,
            tears_text,
            pi_text_1,
            pi_text_2,
            smiley,
        ]
        active_scenes_list.sort(key=lambda scene: scene.zorder, reverse=True)

        for frame_number in itertools.count():
            figure.clear()
            render_axes = figure.add_axes([0.0, 0.0, 1.0, 1.0])
            render_axes.axis("off")
            active_scene_count = len(active_scenes_list)
            if active_scene_count <= 0:
                break
            rendered_scene: bool = False
            for scene_index in range(active_scene_count - 1, -1, -1):
                scene = active_scenes_list[scene_index]
                if frame_number >= scene.start_frame:
                    if frame_number > scene.end_frame:
                        del active_scenes_list[scene_index]
                    else:
                        render_axes.imshow(next(scene.render_frame))
                        rendered_scene = True
            if rendered_scene is True:
                file_writer.grab_frame(facecolor=BACKGROUND_COLOUR)
Exemple #6
0
def draw_terrain(
    axes_dims: List[float],
    fade_in_frames: int,
    update_frames: int,
    fade_out_frames: int,
    frame_jiggle: float,
) -> Generator[Image.Image, None, None]:
    """
    Generator method to draw California area, large cities and faults
    :param axes_dims: matplotlib offset and dimensions
    :param fade_in_frames: Number of frames to fade in graphic
    :param update_frames: Number of frames to animate for
    :param fade_out_frames: Number of frames to fade out the graphic
    :param frame_jiggle: Random offset to apply to the axes each animation
    :return: generator to produce the PIL Image frames
    """
    # Downloaded http://naciscdn.org/naturalearth/packages/natural_earth_vector.zip and
    # unzipped into project directory
    coastlines_gdf = gpd.read_file(
        "./natural_earth_vector/10m_physical/ne_10m_land_scale_rank2.shp")
    populated_gdf = gpd.read_file(
        "./natural_earth_vector/10m_cultural/ne_10m_populated_places.dbf")

    # Downloaded https://earthquake.usgs.gov/static/lfs/nshm/qfaults/Qfaults_GIS.zip and
    # unzipped into project directory
    faults_gdf = gpd.read_file("./GIS Files/Shapefile/QFaults.shp")
    area = Polygon([(-124, 33.5), (-124, 38), (-115, 38), (-115, 33.5)])
    pop_mask = populated_gdf.within(area)
    california_gdf = populated_gdf.loc[pop_mask]
    california_highpop_gdf = california_gdf[california_gdf["SCALERANK"] < 3]
    fault_mask = faults_gdf.intersects(area)
    im: Image.Image = Image.fromarray(np.zeros((1, 1, 4), dtype=np.uint8))

    figure = plt.figure(figsize=(19.2, 10.8))
    fade_in_alpha = np.power(np.linspace(0, 1, fade_in_frames), 2)
    for alpha in fade_in_alpha:
        figure.clear()
        with plt.style.context("dark_background"):
            ax = figure.add_axes(axes_dims)
            california_highpop_gdf.plot(ax=ax,
                                        zorder=2,
                                        color="blue",
                                        markersize=100)
            coastlines_gdf.plot(ax=ax, zorder=1, color="forestgreen")
            for x, y, label in zip(
                    california_highpop_gdf.geometry.x,
                    california_highpop_gdf.geometry.y,
                    california_highpop_gdf["NAME"],
            ):
                ax.annotate(
                    label,
                    xy=(x, y),
                    xytext=(15, -5),
                    textcoords="offset points",
                    zorder=3,
                    fontsize=30,
                )
            ax.set_xlim(-125, -116.111)
            ax.set_ylim(33.5, 38)
            fault_mask = faults_gdf.intersects(area)
            faults_gdf.loc[fault_mask].plot(color="red",
                                            ax=ax,
                                            zorder=1,
                                            alpha=0,
                                            linewidth=2)
            figure.set_facecolor("None")
            ax.axis("off")
        im = convert_plot_to_image(figure)
        pixels = np.array(im)
        alpha_layer = pixels[:, :, 3]
        alpha_layer[alpha_layer > 0] = int(255 * alpha)
        yield Image.fromarray(pixels)

    for frame_number in range(update_frames):
        figure.clear()
        with plt.style.context("dark_background"):
            jiggled_dims = copy.deepcopy(axes_dims)
            x_jiggle = np.random.random()
            x_jiggle = (x_jiggle * 2 - 1) * frame_jiggle
            y_jiggle = np.random.random()
            y_jiggle = (y_jiggle * 2 - 1) * frame_jiggle
            jiggled_dims[0] += x_jiggle
            jiggled_dims[1] += y_jiggle
            tear_alpha = (np.sin(frame_number / 4) + 1) / 2
            ax = figure.add_axes(jiggled_dims)
            california_highpop_gdf.plot(ax=ax,
                                        zorder=2,
                                        color="blue",
                                        markersize=100)
            coastlines_gdf.plot(ax=ax, zorder=1, color="forestgreen")
            for x, y, label in zip(
                    california_highpop_gdf.geometry.x,
                    california_highpop_gdf.geometry.y,
                    california_highpop_gdf["NAME"],
            ):
                ax.annotate(
                    label,
                    xy=(x, y),
                    xytext=(15, -5),
                    textcoords="offset points",
                    zorder=3,
                    fontsize=30,
                )
            ax.set_xlim(-125, -116.111)
            ax.set_ylim(33.5, 38)
            faults_gdf.loc[fault_mask].plot(color="red",
                                            ax=ax,
                                            zorder=1,
                                            alpha=tear_alpha,
                                            linewidth=2)
            figure.set_facecolor("None")
            ax.axis("off")
        im = convert_plot_to_image(figure)
        yield im

    fade_out_alpha = np.power(np.linspace(1, 0, fade_out_frames), 2)
    for frame_number in range(fade_out_frames):
        alpha = fade_out_alpha[frame_number]
        figure.clear()
        with plt.style.context("dark_background"):
            jiggled_dims = copy.deepcopy(axes_dims)
            x_jiggle = np.random.random()
            x_jiggle = (x_jiggle * 2 - 1) * frame_jiggle
            y_jiggle = np.random.random()
            y_jiggle = (y_jiggle * 2 - 1) * frame_jiggle
            jiggled_dims[0] += x_jiggle
            jiggled_dims[1] += y_jiggle
            tear_alpha = (np.sin((update_frames + frame_number) / 4) + 1) / 2
            ax = figure.add_axes(jiggled_dims)
            california_highpop_gdf.plot(ax=ax,
                                        zorder=2,
                                        color="blue",
                                        markersize=100)
            coastlines_gdf.plot(ax=ax, zorder=1, color="forestgreen")
            for x, y, label in zip(
                    california_highpop_gdf.geometry.x,
                    california_highpop_gdf.geometry.y,
                    california_highpop_gdf["NAME"],
            ):
                ax.annotate(
                    label,
                    xy=(x, y),
                    xytext=(15, -5),
                    textcoords="offset points",
                    zorder=3,
                    fontsize=30,
                )
            ax.set_xlim(-125, -116.111)
            ax.set_ylim(33.5, 38)
            faults_gdf.loc[fault_mask].plot(color="red",
                                            ax=ax,
                                            zorder=1,
                                            alpha=tear_alpha,
                                            linewidth=2)
            figure.set_facecolor("None")
            ax.axis("off")
        im = convert_plot_to_image(figure)
        pixels = np.array(im)
        alpha_layer = pixels[:, :, 3]
        alpha_layer[alpha_layer > 0] = int(255 * alpha)
        yield Image.fromarray(pixels)

    # Stay black for the remainder
    black_screen = np.array(im)
    black_screen[:, :, :] = 0
    im = Image.fromarray(black_screen)
    while True:
        yield im
Exemple #7
0
def draw_learning_curve(
    topo_axes_dims: List[float],
    learning_curve_axes_dims: List[float],
    fade_in_frames: int,
    update_frames: int,
    persist_frames: int,
    fade_out_frames: int,
) -> Generator[Image.Image, None, None]:
    """
    Generator method to draw a mock logistic regression and learning curve
    :param topo_axes_dims: logistic regression topology axes
    :param learning_curve_axes_dims: learning curve plot axes
    :param fade_in_frames: Number of frames to fade in the visual
    :param update_frames: Number of frames to animate the graphic for
    :param persist_frames: Number of frames to persist the graphic
    :param fade_out_frames: Number of frames to fade out the graphic
    :return: generator for producing the PIL Image frames
    """
    weights = 41
    lines = np.zeros((weights + 2, 2, 2))
    lines[:weights, 0, 0] = 20
    lines[:weights, 0, 1] = np.linspace(-420, 420, weights)
    lines[:weights, 1, 0] = 300
    lines[:weights, 1, 1] = np.linspace(-100, 100, weights)
    lines[weights] = np.array([[470, 0], [590, 0]])
    lines[weights + 1] = np.array([[750, 0], [870, 0]])
    colors = np.zeros((weights + 2, 4))
    colors[:, [2, 3]] = 1
    line_widths = np.ones(weights + 2) * 2
    line_widths[weights:] = 5

    epoch = np.linspace(0, 20, update_frames)
    error = (1.8 - 1.7 / (1 + np.exp(-epoch))) + np.random.randn(
        update_frames) * np.linspace(0, 0.005, update_frames)

    figure = plt.figure(figsize=(19.2, 10.8))
    colors[:weights, 2] = np.random.random(weights)
    with plt.style.context("dark_background"):
        draw_learning_curve_axes(
            topo_axes_dims,
            learning_curve_axes_dims,
            epoch,
            error,
            figure,
            lines,
            colors,
            line_widths,
            0,
        )
        figure.set_facecolor("None")
    im = convert_plot_to_image(figure)

    # Fade in the axes over this many frames
    fade_in_alpha = np.power(np.linspace(0, 1, fade_in_frames), 2)
    for alpha in fade_in_alpha:
        pixels = np.array(im)
        alpha_layer = pixels[:, :, 3]
        alpha_layer[alpha_layer > 0] = int(255 * alpha)
        yield Image.fromarray(pixels)

    for frame in range(update_frames):
        colors[:weights, 2] = np.random.random(weights)
        figure.clear()
        with plt.style.context("dark_background"):
            draw_learning_curve_axes(
                topo_axes_dims,
                learning_curve_axes_dims,
                epoch,
                error,
                figure,
                lines,
                colors,
                line_widths,
                frame,
            )
            figure.set_facecolor("None")
        im = convert_plot_to_image(figure)
        yield im

    for frame in range(persist_frames):
        yield im

    # Fade out the image over this many frames
    fade_out_alpha = np.power(np.linspace(1, 0, fade_out_frames), 2)
    for alpha in fade_out_alpha:
        pixels = np.array(im)
        alpha_layer = pixels[:, :, 3]
        alpha_layer[alpha_layer > 0] = int(255 * alpha)
        yield Image.fromarray(pixels)

    # Stay black for the remainder
    black_screen = np.array(im)
    black_screen[:, :, :] = 0
    im = Image.fromarray(black_screen)
    while True:
        yield im
Exemple #8
0
def draw_eye(axes_dims: List[float], persist_frames: int,
             fade_out_frames: int) -> Generator[Image.Image, None, None]:
    """
    Generator method for rendering a stylized eye
    :param axes_dims: offset and dimensions of the axes to render to
    :param persist_frames: Number of frames to persist the frames to
    :param fade_out_frames: Number of frames to fade out the eye
    :return: Generator for producing PIL Image frames
    """
    interval_count = 361
    angle = np.linspace(0, np.pi * 2.0, interval_count)
    radius = np.array([num % 2
                       for num in range(0, interval_count)]) * 2.5 + 1.5
    x = radius * np.cos(angle)
    y = radius * np.sin(angle)
    iris = np.vstack([x.reshape(1, -1), y.reshape(1, -1)])
    intervals = np.linspace(-7.05, 7.05, interval_count)
    positive_curve = 0.075 * intervals**2 - 3.75
    negative_curve = -0.075 * (intervals**2) + 3.75
    im: Image.Image = Image.fromarray(np.zeros((1, 1, 4), dtype=np.uint8))
    figure = plt.figure(figsize=(19.2, 10.8))

    for i in range(1, interval_count + 3, 3):
        figure.clear()

        # Draw Iris
        ax = figure.add_axes(axes_dims)
        ax.fill_between(
            intervals[interval_count - i:],
            positive_curve[interval_count - i:],
            negative_curve[interval_count - i:],
            color="white",
            zorder=1,
        )
        ax.plot(iris[0, 0:i],
                iris[1, 0:i],
                linewidth=5,
                color="steelblue",
                zorder=3)
        ax.fill_between(
            intervals,
            np.ones(interval_count) * 5,
            negative_curve,
            color="black",
            alpha=1.0,
            zorder=4,
        )
        ax.fill_between(
            intervals,
            -np.ones(interval_count) * 5,
            positive_curve,
            color="black",
            alpha=1.0,
            zorder=4,
        )
        ax.set_xlim(-9.6, 9.6)
        ax.set_ylim(-4.32, 4.32)
        ax.axis("off")
        patch = patches.Circle((0, 0), radius=4.02, color="black", zorder=2)
        ax.add_patch(patch)

        im = convert_plot_to_image(figure)
        yield im

    # Keep the image for this many frames
    for i in range(persist_frames):
        yield im

    # Fade out the image over this many frames
    fade_out_alpha = np.power(np.linspace(1, 0, fade_out_frames), 2)
    for alpha in fade_out_alpha:
        pixels = np.array(im)
        alpha_layer = pixels[:, :, 3]
        alpha_layer[alpha_layer > 0] = int(255 * alpha)
        yield Image.fromarray(pixels)

    # Stay black for the remainder
    black_screen = np.array(im)
    black_screen[:, :, :] = 0
    im = Image.fromarray(black_screen)
    while True:
        yield im
Exemple #9
0
def draw_gaussian(
    axes_dims: List[float],
    fade_in_frames: int,
    update_frames: int,
    persist_frames: int,
    fade_out_frames: int,
) -> Generator[Image.Image, None, None]:
    """
    Generator method for drawing Gaussian
    :param axes_dims: Offset and dimensions of the plot axes
    :param fade_in_frames: Number of frames to fade in the graphic
    :param update_frames: Number of frames to update the graphic
    :param persist_frames: Number of frames to persist the graphic
    :param fade_out_frames: Number of frames to fade out the graphic
    :return: generator for producing the PIL Image frames
    """
    figure = plt.figure(figsize=(19.2, 10.8))
    with plt.style.context("dark_background"):
        ax = figure.add_axes(axes_dims)
        ax.spines["right"].set_visible(False)
        ax.spines["top"].set_visible(False)
        ax.spines["left"].set_linewidth(2)
        ax.spines["bottom"].set_linewidth(2)
        ax.set_xlim((-8.8, 8.8))
        ax.set_ylim((-0.02, 0.42))
    im = convert_plot_to_image(figure)
    # [0.05, 0.1, 0.9, 0.25]

    # Fade in the axes over this many frames
    fade_in_alpha = np.power(np.linspace(0, 1, fade_in_frames), 2)
    for alpha in fade_in_alpha:
        pixels = np.array(im)
        alpha_layer = pixels[:, :, 3]
        alpha_layer[alpha_layer > 0] = int(255 * alpha)
        yield Image.fromarray(pixels)

    # Animate the Guassian
    mu = 0
    variance = 1
    sigma = np.sqrt(variance)
    for frame in range(0, update_frames * 4, 4):
        figure.clear()
        with plt.style.context("dark_background"):
            ax = figure.add_axes(axes_dims)
            x = np.linspace(mu - 8 * sigma, mu + 8 * sigma, update_frames * 4)
            ax.plot(
                x[:frame],
                stats.norm.pdf(x[:frame], mu, sigma),
                linewidth=3,
                color="skyblue",
            )
            ax.spines["right"].set_visible(False)
            ax.spines["top"].set_visible(False)
            ax.spines["left"].set_linewidth(2)
            ax.spines["bottom"].set_linewidth(2)
            ax.set_xlim((-8.8, 8.8))
            ax.set_ylim((-0.02, 0.42))
        im = convert_plot_to_image(figure)
        yield im

    for frame in range(persist_frames):
        yield im

    # Fade out the image over this many frames
    fade_out_alpha = np.power(np.linspace(1, 0, fade_out_frames), 2)
    for alpha in fade_out_alpha:
        pixels = np.array(im)
        alpha_layer = pixels[:, :, 3]
        alpha_layer[alpha_layer > 0] = int(255 * alpha)
        yield Image.fromarray(pixels)

    # Stay black for the remainder
    black_screen = np.array(im)
    black_screen[:, :, :] = 0
    im = Image.fromarray(black_screen)
    while True:
        yield im
Exemple #10
0
def draw_fire_automata(
    axes_dims: List[float],
    fade_in_frames: int,
    update_frames: int,
    fade_out_frames: int,
) -> Generator[Image.Image, None, None]:
    """
    Generator method for rendering the fire automata
    :param axes_dims: Offset and dimensions of the axes
    :param fade_in_frames: Number of frames to fade in the graphic
    :param update_frames: Number of frames to update the graphic
    :param fade_out_frames: Number of frames to fade out the graphic
    :return: Generator for producing PIL Image frames
    """
    im: Image.Image = Image.fromarray(np.zeros((1, 1, 4), dtype=np.uint8))
    fire_automata = FireAutomata(height=65,
                                 width=64,
                                 decay=0.95,
                                 spawn_points=20)
    figure = plt.figure(figsize=(19.2, 10.8))

    fade_in_alpha = np.power(np.linspace(0, 1, fade_in_frames), 2)
    for alpha in fade_in_alpha:
        figure.clear()
        render_axes = figure.add_axes(axes_dims)
        fire_automata.update_heatmap()
        render_axes.imshow(
            fire_automata.heatmap[:-1, :],
            cmap="hot",
            interpolation="nearest",
            alpha=alpha,
        )
        render_axes.axis("off")
        im = convert_plot_to_image(figure)
        yield im

    for frame_number in range(update_frames):
        figure.clear()
        render_axes = figure.add_axes(axes_dims)
        fire_automata.update_heatmap()
        render_axes.imshow(fire_automata.heatmap[:-1, :],
                           cmap="hot",
                           interpolation="nearest")
        render_axes.axis("off")
        im = convert_plot_to_image(figure)
        yield im

    fade_out_alpha = np.power(np.linspace(1, 0, fade_out_frames), 2)
    for alpha in fade_out_alpha:
        figure.clear()
        render_axes = figure.add_axes(axes_dims)
        fire_automata.update_heatmap()
        render_axes.imshow(
            fire_automata.heatmap[:-1, :],
            cmap="hot",
            interpolation="nearest",
            alpha=alpha,
        )
        render_axes.axis("off")
        im = convert_plot_to_image(figure)
        yield im

    # Stay black for the remainder
    black_screen = np.array(im)
    black_screen[:, :, :] = 0
    im = Image.fromarray(black_screen)
    while True:
        yield im
Exemple #11
0
def draw_text(
    sentence: str,
    text_pos_list: List[int],
    alpha_transitions: int,
    persist_frames: int,
    fade_out_frames: int,
    font_size: int,
    left_offset: float,
    bottom_offset: float,
) -> Generator[Image.Image, None, None]:
    """
    Renders a sentence with configurable phrase boundaries
    :param sentence: Full text to render
    :param text_pos_list: Character offsets in the sentence to fade in
    :param alpha_transitions: Number of alpha increments to fade in each phrase
    :param persist_frames: Number of frames to persist the sentence once drawn
    :param fade_out_frames: Number of frames to fade out the sentence
    :param font_size: Size of the font to render the sentence with
    :param left_offset: axes offset for the text from the left boundary
    :param bottom_offset: axes offset for the text from the bottom boundary
    :return: Generator for producing PIL Image frames
    """
    im: Image.Image = Image.fromarray(np.zeros((1, 1, 4), dtype=np.uint8))
    figure = plt.figure(figsize=(19.2, 10.8))
    alpha_array = np.power(np.linspace(0, 1, alpha_transitions), 2)
    for idx, text_pos in enumerate(text_pos_list):
        for alpha in alpha_array:
            figure.clear()
            text_axes = figure.add_axes([0.0, 0.0, 1.0, 1.0])
            text_axes.axis("off")

            if idx > 0:
                text_axes.text(
                    left_offset,
                    bottom_offset,
                    s=sentence[:text_pos_list[idx - 1]],
                    fontsize=font_size,
                    style="oblique",
                    ha="left",
                    va="bottom",
                    color="white",
                    alpha=1.0,
                )

            text_axes.text(
                left_offset,
                bottom_offset,
                s=sentence[:text_pos],
                fontsize=font_size,
                style="oblique",
                ha="left",
                va="bottom",
                color="white",
                alpha=alpha,
            )
            im = convert_plot_to_image(figure)
            yield im

    # Keep the image for this many frames
    for i in range(persist_frames):
        yield im

    # Fade out the image over this many frames
    fade_out_alpha = np.power(np.linspace(1, 0, fade_out_frames), 2)
    for alpha in fade_out_alpha:
        figure.clear()
        text_axes = figure.add_axes([0.0, 0.0, 1.0, 1.0])
        text_axes.axis("off")
        text_axes.text(
            left_offset,
            bottom_offset,
            s=sentence,
            fontsize=font_size,
            style="oblique",
            ha="left",
            va="bottom",
            color="white",
            alpha=alpha,
        )
        im = convert_plot_to_image(figure)
        yield im

    # Stay black for the remainder
    black_screen = np.array(im)
    black_screen[:, :, :] = 0
    im = Image.fromarray(black_screen)
    while True:
        yield im