iterative_methods 0.2.1

Iterative methods and associated utilities as StreamingIterators.
Documentation
from util import error_message
import sys
import os
from operator import itemgetter
try:
    import numpy as np
    import yaml
    import plotly.graph_objects as go
except ModuleNotFoundError as error:
    print(f"ModuleNotFoundError:", error, error_message)
    sys.exit(1)


parameters = {}
with open("./visualizations_python/parameters_for_histogram.yaml") as parameters_file:

    parameters = yaml.load(parameters_file, Loader=yaml.CLoader)

with open(parameters["reservoir_samples_file"]) as res_file, open(
    parameters["stream_file"]
) as pop_file:

    capacity = int(parameters["capacity"])
    num_res = int(parameters["num_res"])
    stream_size = int(parameters["stream_size"])
    print("capacity, num_res:", capacity, num_res)
    reservoirs = yaml.load_all(res_file, Loader=yaml.CLoader)
    stream = yaml.load_all(pop_file, Loader=yaml.CLoader)
    stream = [value for i, value in stream]
    stream = np.array(stream, dtype=float)
    arr = np.full((capacity * num_res, 2), 0, dtype=float)
    for i, res in enumerate(reservoirs):
        ind = max(map(itemgetter(0), res))
        res = list(map(itemgetter(1), res))
        arr[i * capacity : (i + 1) * capacity, 0] = np.full(capacity, ind)
        arr[i * capacity : (i + 1) * capacity, 1] = np.array(res)

    sigma = float(parameters["sigma"])
    xm = np.min(stream) - 0.2
    xM = np.max(stream) + 0.2
    ym = 0
    yM = 0.3
    bin_size = parameters["bin_size"]

    # initialize the reservoir
    current_res = arr[:capacity]

    def make_res(ind):
        """
        This function returns the most recent reservoir given the
        index "ind" of the portion of the stream that has been processed.
        Used in creating the histograms in the frames of the animation.
        """
        if ind > current_res[0, 0]:
            res = arr[arr[:, 0] == ind]
            if res.size > 0:
                return res
        return current_res

    # duration of animation in milliseconds
    total_duration = 4 * 1000
    skip_size = 20
    num_frames = stream_size // skip_size
    frame_duration = total_duration // num_frames
    print("frame duration:", frame_duration)

    fig = go.Figure()
    fig.layout = go.Layout(
        xaxis=dict(range=[xm, xM], autorange=False, zeroline=False, fixedrange=True),
        yaxis=dict(range=[ym, yM], autorange=False, zeroline=False, fixedrange=True),
        hovermode="closest",
        updatemenus=[
            dict(
                type="buttons",
                buttons=[
                    dict(
                        label="Play",
                        method="animate",
                        args=[
                            None,
                            {
                                "frame": {"duration": frame_duration, "redraw": True},
                                "fromcurrent": True,
                                "transition": {"duration": 0},
                            },
                        ],
                    ),
                    {
                        "args": [
                            [None],
                            {
                                "frame": {"duration": 0, "redraw": True},
                                "mode": "immediate",
                                "transition": {"duration": 0},
                            },
                        ],
                        "label": "Pause",
                        "method": "animate",
                    },
                ],
            )
        ],
        barmode="group",
        bargroupgap=0.1,
    )

    # to adjust position of play/pause buttons
    fig.update_layout(
        updatemenus=[
            dict(
                type="buttons",
                direction="down",
                pad={"r": 10, "t": 10},
                showactive=True,
                x=-0.1,
                xanchor="right",
                y=1.0,
                yanchor="top",
            ),
        ],
        legend=dict(
            yanchor="top", y=1.00, xanchor="left", x=0.01, bgcolor="rgba(0,0,0,0)"
        ),
    )

    fig.update_layout(
        annotations=[
            dict(
                xref="x",
                yref="y",
                showarrow=False,
                x=xM-0.2,
                y=0.22,
                text=f"Percent of Stream Processed: {0}",
                font=dict(color="black"),
                font_size=14,
                xanchor="right",
                opacity=1.0,
            ),
            dict(
                xref="x",
                yref="y",
                showarrow=False,
                x=xM-0.2,
                y=0.17,
                text=f"Reservoir Index: {0}",
                font=dict(color="black"),
                font_size=14,
                xanchor="right",
                opacity=1.0,
            ),
        ]
    ),

    fig.add_trace(
        go.Histogram(
            x=stream[:capacity],
            xbins_size=bin_size,
            histnorm="probability",
            marker_color="#FCA000",
            opacity=0.75,
            name=f"Stream Distribution (Stream Size: {stream_size})",
        )
    )

    fig.add_trace(
        go.Histogram(
            x=current_res[:, 1],
            xbins_size=bin_size,
            histnorm="probability",
            bingroup=2,
            marker_color="#539A99",
            opacity=0.75,
            name=f"Reservoir Distribution (Capacity: {capacity})",
        )
    )

    fig_frames = []
    res_num = 0
    max_index = current_res[0, 0]
    for i in range(capacity - 1, stream_size):
        current_res = make_res(i)        
        if current_res[0, 0] > max_index:
            max_index = current_res[0, 0]
            res_num += 1
        if i % skip_size == 0:
            fig_frames.append(
                go.Frame(
                    data=[
                        go.Histogram(
                            x=stream[:i],                            
                            xbins_size=bin_size,
                            histnorm="probability",                            
                            marker_color="#FCA000",
                            opacity=0.75,
                            name=f"Stream Distribution (Stream Size: {stream_size})",
                        ),
                        go.Histogram(
                            x=current_res[:, 1],
                            xbins_size=bin_size,
                            histnorm="probability",                            
                            marker_color="#539A99",
                            opacity=0.75,
                            name=f"Reservoir Distribution (Capacity: {capacity})",
                        ),
                    ],
                    layout=go.Layout(
                        annotations=[
                            dict(
                                xref="x",
                                yref="y",
                                showarrow=False,
                                x=xM-0.2,
                                y=0.22,
                                text=f"Percent of Stream Processed: {(100*i) // stream_size}",
                                font=dict(color="black"),
                                font_size=14,
                                xanchor="right",                                
                                opacity=1.0,
                            ),
                            dict(
                                xref="x",
                                yref="y",
                                showarrow=False,
                                x=xM-0.2,
                                y=0.17,
                                text=f"Reservoir Index: {res_num}",
                                font=dict(color="black"),
                                font_size=14,
                                xanchor="right",                                
                                opacity=1.0,
                            ),
                        ]
                    ),
                )
            )
    fig.frames = fig_frames

    # To export:
    if not os.path.exists("visualizations"):
        os.mkdir("visualizations")

    fig.update_layout(paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="#c2d1ef")
    config = {"staticPlot": True, "displayModeBar": False}
    fig.write_html(
        file="visualizations/reservoir_histogram_animation.html",
        config=config,
        auto_play=False,
    )