Source code for desdeo_emo.utilities.plotlyanimate

from typing import Union

import numpy as np
import pandas as pd
import plotly.graph_objs as go
from plotly.offline.offline import plot


[docs]def animate_init_(data: Union[np.ndarray, pd.DataFrame, list], filename: str) -> dict: """Plot the first (or zeroth) iteration of a population. Intended as a frames object. Plots Scatter for 2D and 3D data. Plots parallel coordinate plot for higher dimensional data. Parameters ---------- data : Union[np.ndarray, pd.DataFrame, list] Contains the data to be plotted. Each row is an individual's objective values. filename : str Contains the name of the file to which the plot is saved. Returns ------- dict Plotly figure object """ numobj = data.shape[1] if numobj == 2: figure = animate_2d_init_(data, filename) elif numobj == 3: figure = animate_3d_init_(data, filename) elif numobj >= 4: figure = animate_parallel_coords_init_(data, filename) print("Plot saved as: ", filename) print("View the plot by opening the file in browser.") print("To view the plot in Jupyter Notebook, use the IFrame command.") return figure
[docs]def animate_next_( data: Union[np.ndarray, pd.DataFrame, list], figure: dict, filename: str, generation: int = None, ) -> dict: """Plot the next set of individuals in an animation. Plots scatter for 2D and 3D data, parallel coordinate plot for 4D and up. Parameters ---------- data : Union[np.ndarray, pd.DataFrame, list] The objective values to be plotted figure : dict Plotly figure object compatible dict filename : str Name of the file to which the plot is saved generation : int Iteration Number Returns ------- dict Plotly Figure Object """ numobj = data.shape[1] if generation is None: generation = len(figure["frames"]) if numobj == 2: figure = animate_2d_next_(data, figure, filename, generation) elif numobj == 3: figure = animate_3d_next_(data, figure, filename, generation) elif numobj >= 4: figure = animate_parallel_coords_next_(data, figure, filename, generation) return figure
[docs]def animate_2d_init_( data: Union[np.ndarray, pd.DataFrame, list], filename: str ) -> dict: """Initiate a 2D scatter animation. Only for 2D data. Parameters ---------- data : Union[np.ndarray, pd.DataFrame, list] Objective values filename : str Name of the file to which plot is saved Returns ------- dict Plotly Figure Object """ figure = {"data": [], "layout": {}, "frames": []} figure["layout"]["xaxis"] = {"autorange": True} figure["layout"]["yaxis"] = {"autorange": True} figure["layout"]["hovermode"] = "closest" figure["layout"]["sliders"] = { "args": ["transition", {"duration": 400, "easing": "cubic-in-out"}], "initialValue": "1952", "plotlycommand": "animate", "visible": True, } sliders_dict = { "active": 0, "yanchor": "top", "xanchor": "left", "currentvalue": { "font": {"size": 20}, "prefix": "Iteration:", "visible": True, "xanchor": "right", }, "transition": {"duration": 300, "easing": "cubic-in-out"}, "pad": {"b": 10, "t": 50}, "len": 0.9, "x": 0.1, "y": 0, "steps": [], } figure["layout"]["sliders"] = [sliders_dict] data_dict = { "x": list(data[:, 0]), "y": list(data[:, 1]), "mode": "markers", "marker": { "size": 5, "color": "rgba(255, 182, 193, .9)", "line": dict(width=2), }, } figure["data"].append(data_dict) plot(figure, filename=filename) animate_2d_next_(data, figure, filename, 0) return figure
[docs]def animate_2d_next_( data: Union[np.ndarray, pd.DataFrame, list], figure: dict, filename: str, generation: int, ) -> dict: """Plot the next set of individuals in a 2D scatter animation. Parameters ---------- data : Union[np.ndarray, pd.DataFrame, list] The objective values to be plotted figure : dict Plotly figure object compatible dict filename : str Name of the file to which the plot is saved generation : int Iteration Number Returns ------- dict Plotly Figure Object """ frame = {"data": [], "name": str(generation)} sliders_dict = figure["layout"]["sliders"][0] data_dict = { "x": list(data[:, 0]), "y": list(data[:, 1]), "mode": "markers", "marker": { "size": 5, "color": "rgba(255, 182, 193, .9)", "line": dict(width=2), }, } frame["data"].append(data_dict) figure["frames"].append(frame) slider_step = { "args": [ [generation], { "frame": {"duration": 300, "redraw": False}, "mode": "immediate", "transition": {"duration": 300}, }, ], "label": generation, "method": "animate", } sliders_dict["steps"].append(slider_step) figure["layout"]["sliders"] = [sliders_dict] plot(figure, auto_open=False, filename=filename) return figure
[docs]def animate_3d_init_( data: Union[np.ndarray, pd.DataFrame, list], filename: str ) -> dict: """Plot the first (or zeroth) iteration of a population. Intended as a frames object. Plots Scatter 3D data. Parameters ---------- data : Union[np.ndarray, pd.DataFrame, list] Contains the data to be plotted. Each row is an individual's objective values. filename : str Contains the name of the file to which the plot is saved. Returns ------- dict Plotly figure object """ figure = {"data": [], "layout": {}, "frames": []} figure["layout"]["hovermode"] = "closest" figure["layout"]["sliders"] = { "args": ["transition", {"duration": 400, "easing": "cubic-in-out"}], "initialValue": "1", "plotlycommand": "animate", "visible": True, } sliders_dict = { "active": 0, "yanchor": "top", "xanchor": "left", "currentvalue": { "font": {"size": 20}, "prefix": "Iteration:", "visible": True, "xanchor": "right", }, "transition": {"duration": 300, "easing": "cubic-in-out"}, "pad": {"b": 10, "t": 50}, "len": 0.9, "x": 0.1, "y": 0, "steps": [], } figure["layout"]["sliders"] = [sliders_dict] figure["layout"]["scene"] = dict( xaxis=dict( backgroundcolor="rgb(200, 200, 230)", gridcolor="rgb(255, 255, 255)", showbackground=True, zerolinecolor="rgb(255, 255, 255)", ), yaxis=dict( backgroundcolor="rgb(230, 200,230)", gridcolor="rgb(255, 255, 255)", showbackground=True, zerolinecolor="rgb(255, 255, 255)", ), zaxis=dict( backgroundcolor="rgb(230, 230,200)", gridcolor="rgb(255, 255, 255)", showbackground=True, zerolinecolor="rgb(255, 255, 255)", ), ) data_dict = go.Scatter3d( x=list(data[:, 0]), y=list(data[:, 1]), z=list(data[:, 2]), mode="markers", marker=dict( size=8, color=data[:, 2], colorscale="Viridis", opacity=0.5, line=dict(width=2, color="black", colorscale="Viridis"), ), ) figure["data"].append(data_dict) plot(figure, filename=filename) animate_3d_next_(data, figure, filename, 0) return figure
[docs]def animate_3d_next_( data: Union[np.ndarray, pd.DataFrame, list], figure: dict, filename: str, generation: int, ) -> dict: """Plot the next set of individuals in an animation. Plots scatter for 3D data. Parameters ---------- data : Union[np.ndarray, pd.DataFrame, list] The objective values to be plotted figure : dict Plotly figure object compatible dict filename : str Name of the file to which the plot is saved generation : int Iteration Number Returns ------- dict Plotly Figure Object """ frame = {"data": [], "name": str(generation)} sliders_dict = figure["layout"]["sliders"][0] data_dict = go.Scatter3d( x=list(data[:, 0]), y=list(data[:, 1]), z=list(data[:, 2]), mode="markers", marker=dict( size=8, color=data[:, 2], colorscale="Viridis", opacity=0.5, line=dict(width=2, color="black", colorscale="Viridis"), ), ) frame["data"].append(data_dict) figure["frames"].append(frame) slider_step = { "args": [ [generation], { "frame": {"duration": 300, "redraw": True}, "mode": "immediate", "transition": {"duration": 300}, }, ], "label": generation, "method": "animate", } sliders_dict["steps"].append(slider_step) figure["layout"]["sliders"] = [sliders_dict] plot(figure, auto_open=False, filename=filename) return figure
[docs]def animate_parallel_coords_init_( data: Union[np.ndarray, pd.DataFrame, list], filename: str ) -> dict: """Plot the first (or zeroth) iteration of a population. Intended as a frames object. Plots parallel coordinate plot for >3D data. Parameters ---------- data : Union[np.ndarray, pd.DataFrame, list] Contains the data to be plotted. Each row is an individual's objective values. filename : str Contains the name of the file to which the plot is saved. Returns ------- dict Plotly figure object """ figure = {"data": [], "layout": {}, "frames": []} objectives = pd.DataFrame(data) figure["layout"]["hovermode"] = "closest" figure["layout"]["sliders"] = { "args": ["transition", {"duration": 400, "easing": "cubic-in-out"}], "initialValue": "1952", "plotlycommand": "animate", "visible": True, } sliders_dict = { "active": 0, "yanchor": "top", "xanchor": "left", "currentvalue": { "font": {"size": 20}, "prefix": "Iteration:", "visible": True, "xanchor": "right", }, "transition": {"duration": 300, "easing": "cubic-in-out"}, "pad": {"b": 10, "t": 50}, "len": 0.9, "x": 0.1, "y": 0, "steps": [], } figure["layout"]["sliders"] = [sliders_dict] dimensions = [ dict( range=[min(objectives[column]), max(objectives[column])], label="f" + str(column), values=objectives[column], ) for column in objectives ] line = dict( color=objectives[0], colorscale="Viridis", showscale=True, cmin=min(objectives[objectives.columns[0]]), cmax=max(objectives[objectives.columns[0]]), ) data_dict = go.Parcoords(line=line, dimensions=dimensions) figure["data"].append(data_dict) plot(figure, filename=filename) animate_parallel_coords_next_(data, figure, filename, 0) return figure
[docs]def animate_parallel_coords_next_( data: Union[np.ndarray, pd.DataFrame, list], figure: dict, filename: str, generation: int, ) -> dict: """Plot the next set of individuals in an animation. Plots parallel coordinate plot for 4D and up. Parameters ---------- data : Union[np.ndarray, pd.DataFrame, list] The objective values to be plotted figure : dict Plotly figure object compatible dict filename : str Name of the file to which the plot is saved generation : int Iteration Number Returns ------- dict Plotly Figure Object """ frame = {"data": [], "name": str(generation)} objectives = pd.DataFrame(data) sliders_dict = figure["layout"]["sliders"][0] dimensions = [ dict( range=[min(objectives[column]), max(objectives[column])], label="f" + str(column), values=objectives[column], ) for column in objectives ] line = dict( color=objectives[0], colorscale="Viridis", showscale=True, cmin=min(objectives[objectives.columns[0]]), cmax=max(objectives[objectives.columns[0]]), ) data_dict = go.Parcoords(line=line, dimensions=dimensions) frame["data"].append(data_dict) figure["frames"].append(frame) slider_step = { "args": [ [generation], { "frame": {"duration": 300, "redraw": True}, "mode": "immediate", "transition": {"duration": 300}, }, ], "label": generation, "method": "animate", } sliders_dict["steps"].append(slider_step) figure["layout"]["sliders"] = [sliders_dict] plot(figure, auto_open=False, filename=filename) return figure
[docs]def test(): data1 = np.random.rand(100, 3) data2 = np.square(data1) data3 = np.square(data2) data4 = np.square(data3) data = [data2, data3, data4] filename = "firsttest.html" figure = animate_3d_init_(data1, filename) for i in range(1, 4): figure = animate_3d_next_(data[i - 1], figure, filename, i)
[docs]def test2(): data = np.random.rand(100, 1) * np.pi obj = np.hstack((data, np.sin(data), np.cos(data), np.log(data))) figure = animate_parallel_coords_init_(obj, "partest.html") for i in range(1, 10): obj = np.hstack((data, np.sin(data / i), np.cos(data / i), np.log(data / i))) figure = animate_parallel_coords_next_(obj, figure, "partest.html", i)