From ced7b657078388fe139d967fd5d6ba3780630110 Mon Sep 17 00:00:00 2001 From: Uri Goldstein Date: Mon, 4 Jul 2022 18:04:35 +0300 Subject: [PATCH] Removing plot generators --- entropylab/pipeline/api/data_writer.py | 44 ------- entropylab/pipeline/api/plot.py | 111 ------------------ entropylab/pipeline/tests/test_async_graph.py | 6 - entropylab/pipeline/tests/test_executor.py | 36 ++---- entropylab/pipeline/tests/test_graph.py | 17 --- entropylab/pipeline/tests/test_plot.py | 21 ---- 6 files changed, 13 insertions(+), 222 deletions(-) delete mode 100644 entropylab/pipeline/api/plot.py delete mode 100644 entropylab/pipeline/tests/test_plot.py diff --git a/entropylab/pipeline/api/data_writer.py b/entropylab/pipeline/api/data_writer.py index cb73b9c8..e55ccf62 100644 --- a/entropylab/pipeline/api/data_writer.py +++ b/entropylab/pipeline/api/data_writer.py @@ -4,8 +4,6 @@ from typing import Any import matplotlib -from bokeh.models import Renderer -from bokeh.plotting import Figure from matplotlib.figure import Figure as matplotlibFigure from plotly import graph_objects as go @@ -75,48 +73,6 @@ class Debug: extra: str -class PlotGenerator(ABC): - """ - An abstract class for plots. - Implementations of this class will let Entropy to save and view plots. - Every implementation can either implement all plotting functions - (within the different environments), or just part of it. - """ - - def __init__(self) -> None: - super().__init__() - - @abstractmethod - def plot_bokeh(self, figure: Figure, data, **kwargs) -> Renderer: - """ - plot the given data within the Bokeh Figure - :param figure: Bokeh figure to plot in - :param data: plot data - :param kwargs: extra parameters for plotting - """ - pass - - @abstractmethod - def plot_matplotlib(self, figure: matplotlibFigure, data, **kwargs): - """ - plot the given data within the matplotlib Figure - :param figure: matplotlib figure - :param data: plot data - :param kwargs: extra parameters for plotting - """ - pass - - @abstractmethod - def plot_plotly(self, figure: go.Figure, data, **kwargs) -> None: - """ - plot the given data within the plot.ly Figure - :param figure: plot.ly figure - :param data: plot data - :param kwargs: extra parameters for plotting - """ - pass - - @dataclass class NodeData: """ diff --git a/entropylab/pipeline/api/plot.py b/entropylab/pipeline/api/plot.py deleted file mode 100644 index b6533bd2..00000000 --- a/entropylab/pipeline/api/plot.py +++ /dev/null @@ -1,111 +0,0 @@ -from typing import List - -import plotly -import plotly.express as px -import plotly.graph_objects as go -from bokeh.models import Renderer -from bokeh.plotting import Figure -from matplotlib.axes import Axes as Axes -from matplotlib.figure import Figure as matplotlibFigure - -from entropylab.pipeline.api.data_writer import PlotGenerator - - -class LinePlotGenerator(PlotGenerator): - def __init__(self) -> None: - super().__init__() - - def plot_matplotlib(self, figure: matplotlibFigure, data, **kwargs) -> Renderer: - raise NotImplementedError() - - def plot_bokeh(self, figure: Figure, data, **kwargs) -> Renderer: - if isinstance(data, List) and len(data) == 2 and len(data[0]) == len(data[1]): - x = data[0] - y = data[1] - return figure.line( - x, - y, - color=kwargs.get("color", "blue"), - legend_label=kwargs.get("label", ""), - ) - else: - raise TypeError("data type is not supported") - - def plot_plotly(self, figure: plotly.graph_objects.Figure, data, **kwargs): - if isinstance(data, List) and len(data) == 2 and len(data[0]) == len(data[1]): - x = data[0] - y = data[1] - color = kwargs.pop("color", "blue") - figure.add_trace( - go.Scatter( - mode="lines", - x=x, - y=y, - line_color=color, - **kwargs, - ) - ) - return figure - else: - raise TypeError("data type is not supported") - - -class CirclePlotGenerator(PlotGenerator): - def __init__(self) -> None: - super().__init__() - - def plot_matplotlib(self, figure: Axes, data, **kwargs): - raise NotImplementedError() - - def plot_bokeh(self, figure: Figure, data, **kwargs) -> Renderer: - if isinstance(data, List) and len(data) == 2 and len(data[0]) == len(data[1]): - x = data[0] - y = data[1] - color = (kwargs.get("color", "blue"),) - return figure.circle( - x, - y, - size=10, - color=color, - legend_label=kwargs.get("label", ""), - alpha=0.5, - ) - else: - raise TypeError("data type is not supported") - - def plot_plotly(self, figure: plotly.graph_objects.Figure, data, **kwargs): - if isinstance(data, List) and len(data) == 2 and len(data[0]) == len(data[1]): - x = data[0] - y = data[1] - color = kwargs.pop("color", "blue") - # noinspection PyTypeChecker - figure.add_trace( - go.Scatter( - mode="markers", - x=x, - y=y, - marker_color=color, - marker_size=10, - **kwargs, - ) - ) - return figure - else: - raise TypeError("data type is not supported") - - -class ImShowPlotGenerator(PlotGenerator): - def __init__(self) -> None: - super().__init__() - - def plot_plotly(self, figure: go.Figure, data, **kwargs) -> None: - headtmap_fig = px.imshow(data) - figure.add_trace(headtmap_fig.data[0]) - - return figure - - def plot_bokeh(self, figure: Figure, data, **kwargs) -> Renderer: - raise NotImplementedError() - - def plot_matplotlib(self, figure: matplotlibFigure, data, **kwargs): - raise NotImplementedError() diff --git a/entropylab/pipeline/tests/test_async_graph.py b/entropylab/pipeline/tests/test_async_graph.py index 8d81bf8d..8414829b 100644 --- a/entropylab/pipeline/tests/test_async_graph.py +++ b/entropylab/pipeline/tests/test_async_graph.py @@ -1,7 +1,6 @@ import asyncio import numpy as np -from bokeh.plotting import Figure from entropylab.pipeline.graph_experiment import ( Graph, @@ -136,11 +135,6 @@ def test_async_graph(): results = graph.run().results print(results.get_experiment_info()) - plots = results.get_plots() - for plot in plots: - figure = Figure() - plot.generator.plot_bokeh(figure, plot.plot_data) - # save(figure, f"try{plot.label}.html") def test_async_graph_run_to_node(): diff --git a/entropylab/pipeline/tests/test_executor.py b/entropylab/pipeline/tests/test_executor.py index 339e5116..d2beef49 100644 --- a/entropylab/pipeline/tests/test_executor.py +++ b/entropylab/pipeline/tests/test_executor.py @@ -1,11 +1,10 @@ from datetime import datetime import pytest +from plotly import express as px -from entropylab.pipeline.api.data_writer import PlotSpec -from entropylab.pipeline.api.execution import EntropyContext -from entropylab.pipeline.api.plot import CirclePlotGenerator, LinePlotGenerator from entropylab.components.lab_topology import LabResources, ExperimentResources +from entropylab.pipeline.api.execution import EntropyContext from entropylab.pipeline.results_backend.sqlalchemy.db import SqlAlchemyDB from entropylab.pipeline.script_experiment import Script, script_experiment from entropylab.pipeline.tests.mock_instruments import MockScope @@ -64,14 +63,10 @@ def an_experiment_with_plot(experiment: EntropyContext): experiment.add_result("b_result" + str(i), b1 + i + datetime.now().microsecond) micro = datetime.now().microsecond - experiment.add_plot( - PlotSpec( - label="plot", - story="created this plot in experiment", - generator=CirclePlotGenerator, - ), - data=[ - [ + + experiment.add_figure( + px.scatter( + x=[ 1 * micro, 2 * micro, 3 * micro, @@ -81,20 +76,15 @@ def an_experiment_with_plot(experiment: EntropyContext): 7 * micro, 8 * micro, ], - [0, 1, 2, 3, 4, 5, 6, 7], - ], + y=[0, 1, 2, 3, 4, 5, 6, 7], + ) ) - experiment.add_plot( - PlotSpec( - label="another plot", - story="just showing off now", - generator=LinePlotGenerator, - ), - data=[ - [1, 2, 3, 4, 5, 6, 7, 8], - [4, 5, 6, 7, 0, 1, 2, 3], - ], + experiment.add_figure( + px.line( + x=[1, 2, 3, 4, 5, 6, 7, 8], + y=[4, 5, 6, 7, 0, 1, 2, 3], + ) ) diff --git a/entropylab/pipeline/tests/test_graph.py b/entropylab/pipeline/tests/test_graph.py index 4114c7f1..1e049f2a 100644 --- a/entropylab/pipeline/tests/test_graph.py +++ b/entropylab/pipeline/tests/test_graph.py @@ -1,14 +1,9 @@ import asyncio -import os from time import sleep import pytest -from bokeh.io import save -from bokeh.plotting import Figure -from entropylab.pipeline.api.data_writer import PlotSpec from entropylab.pipeline.api.execution import EntropyContext -from entropylab.pipeline.api.plot import CirclePlotGenerator from entropylab.pipeline.graph_experiment import ( Graph, PyNode, @@ -52,10 +47,6 @@ def d(x, y): async def e(y, z, context: EntropyContext): print(f"Node e resting for {y / z}") print(f"e Result: {y + z}") - context.add_plot( - PlotSpec(CirclePlotGenerator, "the best plot"), - data=[[0, 1, 2, 3, 4, 5], [y + z, 7, 6, 20, 10, 11]], - ) return {"y_z": [0, 1, 2, 3, 4, 5, y + z, 7, 6, 20, 10, 11]} @@ -147,14 +138,6 @@ def test_sync_graph(): results = Graph(None, g, "run_a").run().results print(results.get_experiment_info()) - # TODO: Use figures instead of plots here - plots = results.get_plots() - for plot in plots: - figure = Figure() - plot.generator.plot_bokeh(figure, plot.plot_data) - if not os.path.exists("tests_cache"): - os.mkdir("tests_cache") - save(figure, f"tests_cache/bokeh-exported-{plot.label}.html") def test_sync_graph_run_to_node(): diff --git a/entropylab/pipeline/tests/test_plot.py b/entropylab/pipeline/tests/test_plot.py deleted file mode 100644 index 03c079c0..00000000 --- a/entropylab/pipeline/tests/test_plot.py +++ /dev/null @@ -1,21 +0,0 @@ -import numpy as np -import plotly - -from entropylab.pipeline.api.plot import CirclePlotGenerator, ImShowPlotGenerator -from plotly.graph_objects import Figure - - -def test_circle_plot_plotly(): - target = CirclePlotGenerator() - figure = Figure() - data = [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]] - target.plot_plotly(figure, data) - i = 0 - - -def test_imshow_plot_plotly(): - target = ImShowPlotGenerator() - figure = Figure() - data = np.random.rand(10, 10) - target.plot_plotly(figure, data) - assert isinstance(figure.data[0], plotly.graph_objs._heatmap.Heatmap)