Пример #1
0
def draw_learning_curve_axes(
    topo_axes_dims: List[float],
    learning_curve_axes_dims: List[float],
    epoch: np.ndarray,
    error: np.ndarray,
    figure: figure.Figure,
    lines: np.ndarray,
    colors: np.ndarray,
    line_widths: np.ndarray,
    frame: int,
):
    """
    Render the mock logistic regression and learning curve to their respective axes
    :param topo_axes_dims: logistic regression axes
    :param learning_curve_axes_dims: learning curve plot axes
    :param epoch: array of values for learning curve epoch
    :param error: array of error values for learning curve
    :param figure: figure to render the axes to
    :param lines: Lines in the logistic regression topology
    :param colors: Colors of the lines in the logistic regression
    :param line_widths: Widths of the lines in the logistic regression
    :param frame: frame number of the animation
    """
    lc = mc.LineCollection(lines, colors=colors, linewidths=line_widths)
    topo_ax = figure.add_axes(topo_axes_dims)
    topo_ax.set_xlim((0, 960))
    topo_ax.set_ylim((-420, 420))
    topo_ax.axis("off")
    topo_ax.add_collection(lc)
    topo_ax.text(310, -20, r"$\sum_{j=1}^n x_jw_j$", fontsize=30)
    topo_ax.text(604,
                 -10,
                 r"$\frac{\mathrm{1} }{\mathrm{1} + e^{-net}}$",
                 fontsize=30)
    for i in range(41):
        topo_ax.text(0,
                     -425 + i * 21,
                     f"{np.random.randint(0,2)}",
                     fontsize=10,
                     color="green")
    topo_ax.text(880,
                 -10,
                 f"{np.random.random():0.3f}",
                 fontsize=20,
                 color="green")
    learning_curve_ax = figure.add_axes(learning_curve_axes_dims)
    learning_curve_ax.set_xlim(-1, 21)
    learning_curve_ax.set_ylim(0.01, 1.01)
    learning_curve_ax.set_xlabel("Epochs", fontsize=18)
    learning_curve_ax.set_ylabel("Error", fontsize=18)
    learning_curve_ax.get_xaxis().set_ticks([])
    learning_curve_ax.get_yaxis().set_ticks([])
    learning_curve_ax.spines["right"].set_visible(False)
    learning_curve_ax.spines["top"].set_visible(False)
    learning_curve_ax.spines["left"].set_linewidth(2)
    learning_curve_ax.spines["bottom"].set_linewidth(2)
    learning_curve_ax.plot(epoch[:frame], error[:frame], linewidth=3)
def draw_otf_spectrum(cube, figure=None, subplot=111, title='', grid=True,
                      font_family=None, tick_labels_size=9, xlim=None, ylim=None,
                      show=True, *args, **kwargs):
    import time
    import numpy
    import analyse
    import analyse.plotter
    import matplotlib.figure
    import matplotlib.colors
    import pylab
    t0 = time.time()
    print('[%f] -- %f'%(time.time(), time.time()-t0))
    if not isinstance(figure, matplotlib.figure.Figure):
        if figure is None:
            figure = pylab.figure()
        else:
            figure = pylab.figure(figsize=figure)
    else:
        show = False

    if type(subplot) is int:
        subplot = analyse.plotter.get_subplot(subplot)
    elif type(subplot) in [list, tuple]:
        if len(subplot) == 3:
            subplot = analyse.plotter.get_subplot(subplot)

    nz, ny, nx = cube.data.shape
    spectra = cube.data.T.reshape(nx*ny, nz)
    v = analyse.generate_axis(cube, axis=3) / 1000.

    ax = figure.add_axes(subplot)
    #[ax.plot(v, s, '.b', ms=1, mew=0, alpha=0.1) for s in spectra]
    xd = numpy.array(list(v) * len(spectra))
    yd = spectra.ravel()
    yd[numpy.isnan(yd)] = 0
    histmap, histx, histy = pylab.histogram2d(xd, yd, bins=501)
    histmap = histmap.T
    histmap[numpy.where(histmap==0)] = 0.3
    histmap = numpy.log10(histmap)
    histX, histY = numpy.meshgrid(histx, histy)
    ax.pcolormesh(histX, histY, histmap, vmax=3.3)
    ax.grid(grid)
    ax.set_title(title, size=tick_labels_size+1)
    if xlim is not None: ax.set_xlim(*xlim)
    else: ax.set_xlim(xd.min(), xd.max())
    if ylim is not None: ax.set_ylim(*ylim)
    else: ax.set_ylim(yd.min(), yd.max())
    tx = ax.get_xticks()
    ty = ax.get_yticks()
    ax.set_xticklabels(tx, size=tick_labels_size)
    ax.set_yticklabels(ty, size=tick_labels_size)

    if show:
        pylab.show()

    print('[%f] -- %f'%(time.time(), time.time()-t0))
    return figure
Пример #3
0
def run_ui():
    figure = plt.figure()
    ax = figure.add_axes([.05, .05, .9, .9])
    x = np.linspace(0, np.pi * 8)
    ax.plot(x, np.sin(x))
    canvas = figure.canvas
    frame = canvas.component.getTopLevelAncestor()
    toolbar = plt.get_current_fig_manager().frame.toolbar
    toolbar.add_button(lambda event: popup_script_dlg(canvas), "hand")
    plt.show()
    return frame, canvas, toolbar
Пример #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
Пример #5
0
)
figure.linewidth = 10
# 创建坐标系Axes:图中可以有多个坐标系(同时显示,需要指定位置大小)
#       |- Axis坐标轴(XAxis, YAxis)
#           |- 刻度, 标签,格式化器
# Figure.add_axes(axes对象| 参数)
# 使用函数构建Figure
ax = plt.Axes(
    figure,
    rect=[0.1, 0.5, 0.8, 0.3],
    label='坐标系2',
    facecolor=(0, 0, 1, 1),
    frameon=True,
    xscale='log',  # log是对数坐标
    yscale='linear')
figure.add_axes(ax)

figure.add_axes(
    [0, 1, 0.1, 0.8, 0.3],
    projection='polar',
    label='坐标系1',
    facecolor=(0, 1, 0, 1),
    frameon=True,
    sharex=ax,
    sharey=ax,
    xscale='linear',
    yscale='log',
)

# 绘制图形Artist(分成很多类型:线条,矩形,文本,图像)
Пример #6
0
def plot_spectrum(wavelength,
                  flux,
                  filename="spectrum.png",
                  lambda_limits=None,
                  flux_limits=None,
                  title=None,
                  label=None,
                  figsize=None,
                  step=False,
                  stagger=0.2,
                  features=None,
                  axis_labels=None):
    """
    Plot a spectrum or a collection of spectra and save to disk.

    This function wraps some Matplotlib plotting functionality for
    plotting spectra generated with the :class:`~trident.SpectrumGenerator`.
    In its simplest form, it accepts a wavelength array consisting of
    wavelength values and a corresponding flux array consisting of relative
    flux values, and it plots them and saves to disk.

    In addition, it can plot several spectra on the same axes simultaneously
    by passing a list of arrays to the ``wavelength``, ``flux`` arguments
    (and optionally to the ``label`` and ``step`` keywords).

    Returns the Matplotlib Figure object for further processing.

    **Parameters**

    :wavelength: array of floats or list of arrays of floats

        Wavelength values in angstroms.  Either as an array of floats in the
        case of plotting a single spectrum, or as a list of arrays of floats
        in the case of plotting several spectra on the same axes.

    :flux: array of floats or list of arrays of floats

        Relative flux values (from 0 to 1) corresponding to wavelength array.
        Either as an array of floats in the case of plotting a single
        spectrum, or as a list of arrays of floats in the case of plotting
        several spectra on the same axes.

    :filename: string, optional

        Output filename of the plotted spectrum.  Will be a png file.
        Default: 'spectrum.png'

    :lambda_limits: tuple or list of floats, optional

        The minimum and maximum of the wavelength range (x-axis) for the plot
        in angstroms.  If specified as None, will use whole lambda range
        of spectrum. Example: (1200, 1400) for 1200-1400 Angstroms
        Default: None

    :flux_limits: tuple or list of floats, optional

        The minimum and maximum of the flux range (y-axis) for the plot.
        If specified as None, limits are automatically from
        [0, 1.1*max(flux)]. Example: (0, 1) for normal flux range before
        postprocessing.
        Default: None

    :step: boolean or list of booleans, optional

        Plot the spectrum as a series of step functions.  Appropriate for
        plotting processed and noisy data.  Use a list of booleans when
        plotting multiple spectra, where each boolean corresponds to the entry
        in the ``wavelength`` and ``flux`` lists.

    :title: string, optional

        Optional title for plot
        Default: None

    :label: string or list of strings, optional

        Label for each spectrum to be plotted. Useful if plotting multiple
        spectra simultaneously.  Will automatically trigger a legend to be
        generated.
        Default: None

    :stagger: float, optional

        If plotting multiple spectra on the same axes, do we offset them in
        the y direction?  If set to None, no.  If set to a float, stagger them
        by the flux value specified by this parameter.

    :features: dict, optional

        Include vertical lines with labels to represent certain spectral
        features.  Each entry in the dictionary consists of a key string to
        be overplot and the value float as to where in wavelength space it
        will be plot as a vertical line with the corresponding label.

        Example: features={'Ly a' : 1216, 'Ly b' : 1026}

        Default: None

    :axis_labels: tuple of strings, optional

        Optionally set the axis labels directly.  If set to None, defaults to
        ('Wavelength [$\\rm\\AA$]', 'Relative Flux').
        Default: None

    **Returns**

    Matplotlib Figure object for further processing

    **Example**

    Plot a flat spectrum

    >>> import numpy as np
    >>> import trident
    >>> wavelength = np.arange(1200, 1400)
    >>> flux = np.ones(len(wavelength))
    >>> trident.plot_spectrum(wavelength, flux)

    Generate a one-zone ray, create a Lyman alpha spectrum from it, and add
    gaussian noise to it.  Plot both the raw spectrum and the noisy spectrum
    on top of each other.

    >>> import trident
    >>> ray = trident.make_onezone_ray(column_densities={'H_p0_number_density':1e21})
    >>> sg_final = trident.SpectrumGenerator(lambda_min=1200, lambda_max=1300, dlambda=0.5)
    >>> sg_final.make_spectrum(ray, lines=['Ly a'])
    >>> sg_final.save_spectrum('spec_raw.h5')
    >>> sg_final.add_gaussian_noise(10)
    >>> sg_raw = trident.load_spectrum('spec_raw.h5')
    >>> trident.plot_spectrum([sg_raw.lambda_field, sg_final.lambda_field],
    ... [sg_raw.flux_field, sg_final.flux_field], stagger=0, step=[False, True],
    ... label=['Raw', 'Noisy'], filename='raw_and_noise.png')
    """

    # number of rows and columns
    n_rows = 1
    n_columns = 1

    # blank space between edge of figure and active plot area
    top_buffer = 0.07
    bottom_buffer = 0.15
    left_buffer = 0.06
    right_buffer = 0.03

    # blank space between plots
    hor_buffer = 0.05
    vert_buffer = 0.05

    # calculate the height and width of each panel
    panel_width = ((1.0 - left_buffer - right_buffer -
                    ((n_columns - 1) * hor_buffer)) / n_columns)
    panel_height = ((1.0 - top_buffer - bottom_buffer -
                     ((n_rows - 1) * vert_buffer)) / n_rows)

    # create a figure (figsize is in inches)
    if figsize is None:
        figsize = (12, 4)
    figure = matplotlib.figure.Figure(figsize=figsize, frameon=True)

    # get the row and column number
    my_row = 0
    my_column = 0

    # calculate the position of the bottom, left corner of this plot
    left_side = left_buffer + (my_column * panel_width) + \
                my_column * hor_buffer
    top_side = 1.0 - (top_buffer + (my_row * panel_height) + \
               my_row * vert_buffer)
    bottom_side = top_side - panel_height

    # create an axes object on which we will make the plot
    my_axes = figure.add_axes(
        (left_side, bottom_side, panel_width, panel_height))

    # Are we overplotting several spectra?  or just one?
    if isinstance(flux, list):
        fluxs = flux
    else:
        fluxs = [flux]

    if isinstance(wavelength, list):
        wavelengths = wavelength
    else:
        wavelengths = [wavelength] * len(fluxs)

    if isinstance(step, list):
        steps = step
    else:
        steps = [step] * len(fluxs)

    if isinstance(label, list):
        labels = label
    else:
        labels = [label] * len(fluxs)

    # A running maximum of flux for use in ylim scaling in final plot
    max_flux = 0.

    if isinstance(wavelength, list):
        key = wavelength[0]
    else:
        key = wavelength
    xlabel = _xlabels.get(str(key.units))

    for i, (wavelength, flux) in enumerate(zip(wavelengths, fluxs)):
        # Do we stagger the fluxes?
        if stagger is not None:
            flux -= stagger * i

        # Do we include labels and a legend?
        if steps[i]:
            my_axes.step(wavelength, flux, label=labels[i])
        else:
            my_axes.plot(wavelength, flux, label=labels[i])

        new_max_flux = np.max(flux)
        if new_max_flux > max_flux:
            max_flux = new_max_flux

        # Return the fluxes to their normal values
        # if they've been staggered
        if stagger is not None:
            flux += stagger * i

    # Do we include a title?
    if title is not None:
        my_axes.set_title(title)

    if lambda_limits is None:
        lambda_limits = (wavelength.min(), wavelength.max())
    my_axes.set_xlim(lambda_limits[0], lambda_limits[1])

    if flux_limits is None:
        flux_limits = (0, 1.1 * max_flux)
    my_axes.set_ylim(flux_limits[0], flux_limits[1])
    if axis_labels is None:
        axis_labels = (xlabel, 'Relative Flux')
    my_axes.xaxis.set_label_text(axis_labels[0])
    my_axes.yaxis.set_label_text(axis_labels[1])

    # Don't let the x-axis switch to offset values for tick labels
    my_axes.get_xaxis().get_major_formatter().set_useOffset(False)

    if label is not None: my_axes.legend()

    # Overplot the relevant features on the plot
    if features is not None:
        for feature in features:
            label = feature
            wavelength = features[feature]
            # Draw line
            my_axes.plot([wavelength, wavelength],
                         flux_limits,
                         '--',
                         color='k')
            # Write text
            text_location = flux_limits[1] - 0.05 * (flux_limits[1] -
                                                     flux_limits[0])
            my_axes.text(wavelength,
                         text_location,
                         label,
                         horizontalalignment='right',
                         verticalalignment='top',
                         rotation='vertical')

    mylog.info("Writing spectrum plot to png file: %s" % filename)
    canvas = FigureCanvasAgg(figure)
    canvas.print_figure(filename)
    return figure
Пример #7
0
    def __init__(self, 
            figure,
            left = 0.2, bottom = 0.2, width = 0.6, height = 0.6,
            axes = None,
            polar = None,
            autoscale_both_on = None,
            autoscale_x_on = None,
            autoscale_y_on = None,
            colorbar=None,
            locator_x=None,
            locator_y=None):
        """FIGURE is the matplotlib.figure.Figure instance where to act on.
        AXES is optionally an existing axes instance.  If AXES is not given,
        a new axes instance will be created, either a cartesian, or a polar if
        POLAR is True.
        
        The initial autoscaling is controled by AUTOSCALING_BOTH, 
        AUTOSCALING_X, and AUTOSCALING_Y.  If AUTOSCALING_BOTH is given, it
        overrides AUTOSCALING_X and AUTOSCALING_Y.  If the autoscaling for 
        some axis isn't given (either by AUTOSCALING_BOTH or by the other
        arguments), it defaults to True.
        
        If COLORBAR isn't None, but 'vertical' or 'horizontal', the Axes
        will be initialised by setting the label and ticks position to the
        appropriate position.  This is useful if the Stack is intended to be
        used for a LayerColorbar, since the LayerColorbar cannot draw a
        Colorbar until it has received data, and therefore there would be
        nothing updating the ticks and label positions.
        
        LOCATOR_X and LOCATOR_Y are optional and are the major locator to be
        used for the respective axes."""

        # Define the default values for AUTOSCALING_X/Y.  May be overridden
        # by AUTOSCALING_BOTH if that is given ...

        if autoscale_x_on is None:
            autoscale_x_on = True
        if autoscale_y_on is None:
            autoscale_y_on = True
    
        # Initialise attributes ...

        if axes is None:
            # Create a new axes instance.
            axes = figure.add_axes(
                    (left, bottom, width, height),
                    polar = polar)
            axes.hold(True)

        # Take over the axes.
        self.axes = axes

        # Initialise the title etc. to some values.
        self.title = self.axes.get_title()
        self.title_kwargs = {}
        self.xlabel = self.axes.get_xlabel()
        self.ylabel = self.axes.get_ylabel()

        # Apply the autoscaling ...
        #
        # This will also store the correct values for .xlim and .ylim.
        
        self.set_autoscale_on(
                both_on = autoscale_both_on,
                x_on = autoscale_x_on,
                y_on = autoscale_y_on)

        # Store the locators ...

        self.set_locators(locator_x=locator_x, locator_y=locator_y)

        # Prepare for use as a colorbar ...
        #
        # Do this after setting the locators and not before.  Because
        # set_colorbar() sets also the xticks, but set_locators overrides
        # this by setting the xlocator to AutoLocator(), when done in the
        # wrong order.

        self.set_colorbar(colorbar)
    
        # The layers present.
        self._layers = []
        
        # The layers rendered to the FigureAxes.
        self._layers_drawn = []

        # Whether a reset of the FigureAxes is needed before rendering.  This
        # may occur because:
        #  1.  Layers drawn have changed data.
        #  2.  Layers have been removed.
        self._needs_reset = False
Пример #8
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)
Пример #9
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
Пример #10
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
Пример #11
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
Пример #12
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
Пример #13
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