diff --git a/src/vuecore/plots/__init__.py b/src/vuecore/plots/__init__.py index e69de29..ee13a1d 100644 --- a/src/vuecore/plots/__init__.py +++ b/src/vuecore/plots/__init__.py @@ -0,0 +1,4 @@ +# vuecore/plots/__init__.py +from .plot_factory import create_plot + +__all__ = ["create_plot"] diff --git a/src/vuecore/plots/basic/__init__.py b/src/vuecore/plots/basic/__init__.py index e69de29..b233782 100644 --- a/src/vuecore/plots/basic/__init__.py +++ b/src/vuecore/plots/basic/__init__.py @@ -0,0 +1,12 @@ +# vuecore/plots/basic/__init__.py +from .bar import create_bar_plot +from .box import create_box_plot +from .line import create_line_plot +from .scatter import create_scatter_plot + +__all__ = [ + "create_bar_plot", + "create_box_plot", + "create_line_plot", + "create_scatter_plot", +] diff --git a/src/vuecore/plots/basic/bar.py b/src/vuecore/plots/basic/bar.py index 7f25d2d..ca84bf4 100644 --- a/src/vuecore/plots/basic/bar.py +++ b/src/vuecore/plots/basic/bar.py @@ -2,9 +2,9 @@ import pandas as pd -from vuecore import EngineType -from vuecore.engines import get_builder, get_saver +from vuecore import EngineType, PlotType from vuecore.schemas.basic.bar import BarConfig +from vuecore.plots.plot_factory import create_plot from vuecore.utils.docs_utils import document_pydant_params @@ -19,7 +19,7 @@ def create_bar_plot( Creates, styles, and optionally saves a bar plot using the specified engine. This function serves as the main entry point for users to generate bar plots. - It validates the provided configuration against the BarConfig schema, + It validates the provided configuration against the `BarConfig` schema, retrieves the appropriate plotting builder and saver functions based on the selected engine, builds the plot, and optionally saves it to a file. @@ -63,18 +63,11 @@ def create_bar_plot( * **Python Script:** `docs/api_examples/bar_plot.py` - https://github.com/Multiomics-Analytics-Group/vuecore/blob/main/docs/api_examples/bar_plot.py """ - # 1. Validate configuration using Pydantic. - config = BarConfig(**kwargs) - - # 2. Get the correct builder function from the registry. - builder_func = get_builder(plot_type="bar", engine=engine) - - # 3. Build the figure object. - figure = builder_func(data, config) - - # 4. Save the plot using the correct saver function, if a file_path is provided. - if file_path: - saver_func = get_saver(engine=engine) - saver_func(figure, file_path) - - return figure + return create_plot( + data=data, + config=BarConfig, + plot_type=PlotType.BAR, + engine=engine, + file_path=file_path, + **kwargs, + ) diff --git a/src/vuecore/plots/basic/box.py b/src/vuecore/plots/basic/box.py index 6f3432b..9ece072 100644 --- a/src/vuecore/plots/basic/box.py +++ b/src/vuecore/plots/basic/box.py @@ -2,9 +2,9 @@ import pandas as pd -from vuecore import EngineType -from vuecore.engines import get_builder, get_saver +from vuecore import EngineType, PlotType from vuecore.schemas.basic.box import BoxConfig +from vuecore.plots.plot_factory import create_plot from vuecore.utils.docs_utils import document_pydant_params @@ -19,7 +19,7 @@ def create_box_plot( Creates, styles, and optionally saves a box plot using the specified engine. This function serves as the main entry point for users to generate box plots. - It validates the provided configuration against the BoxConfig schema, + It validates the provided configuration against the `BoxConfig` schema, retrieves the appropriate plotting builder and saver functions based on the selected engine, builds the plot, and optionally saves it to a file. @@ -63,18 +63,11 @@ def create_box_plot( * **Python Script:** `docs/api_examples/box_plot.py` - https://github.com/Multiomics-Analytics-Group/vuecore/blob/main/docs/api_examples/box_plot.py """ - # 1. Validate configuration using Pydantic. - config = BoxConfig(**kwargs) - - # 2. Get the correct builder function from the registry. - builder_func = get_builder(plot_type="box", engine=engine) - - # 3. Build the figure object. - figure = builder_func(data, config) - - # 4. Save the plot using the correct saver function, if a file_path is provided. - if file_path: - saver_func = get_saver(engine=engine) - saver_func(figure, file_path) - - return figure + return create_plot( + data=data, + config=BoxConfig, + plot_type=PlotType.BOX, + engine=engine, + file_path=file_path, + **kwargs, + ) diff --git a/src/vuecore/plots/basic/line.py b/src/vuecore/plots/basic/line.py index 1a87b46..4641fde 100644 --- a/src/vuecore/plots/basic/line.py +++ b/src/vuecore/plots/basic/line.py @@ -2,9 +2,9 @@ import pandas as pd -from vuecore import EngineType -from vuecore.engines import get_builder, get_saver +from vuecore import EngineType, PlotType from vuecore.schemas.basic.line import LineConfig +from vuecore.plots.plot_factory import create_plot from vuecore.utils.docs_utils import document_pydant_params @@ -19,7 +19,7 @@ def create_line_plot( Creates, styles, and optionally saves a line plot using the specified engine. This function serves as the main entry point for users to generate line plots. - It validates the provided configuration against the LineConfig schema, + It validates the provided configuration against the `LineConfig` schema, retrieves the appropriate plotting builder and saver functions based on the selected engine, builds the plot, and optionally saves it to a file. @@ -62,18 +62,11 @@ def create_line_plot( https://vuecore.readthedocs.io/en/latest/api_examples/scatter_plot.html * **Python Script:** `docs/api_examples/line_plot.py` """ - # 1. Validate configuration using Pydantic - config = LineConfig(**kwargs) - - # 2. Get the correct builder function from the registry - builder_func = get_builder(plot_type="line", engine=engine) - - # 3. Build the figure object (the API doesn't know or care what type it is) - figure = builder_func(data, config) - - # 4. Save the plot using the correct saver - if file_path: - saver_func = get_saver(engine=engine) - saver_func(figure, file_path) - - return figure + return create_plot( + data=data, + config=LineConfig, + plot_type=PlotType.LINE, + engine=engine, + file_path=file_path, + **kwargs, + ) diff --git a/src/vuecore/plots/basic/scatter.py b/src/vuecore/plots/basic/scatter.py index 58e846d..affa9e5 100644 --- a/src/vuecore/plots/basic/scatter.py +++ b/src/vuecore/plots/basic/scatter.py @@ -2,9 +2,9 @@ import pandas as pd -from vuecore import EngineType -from vuecore.engines import get_builder, get_saver +from vuecore import EngineType, PlotType from vuecore.schemas.basic.scatter import ScatterConfig +from vuecore.plots.plot_factory import create_plot from vuecore.utils.docs_utils import document_pydant_params @@ -19,7 +19,7 @@ def create_scatter_plot( Creates, styles, and optionally saves a scatter plot using the specified engine. This function serves as the main entry point for users to generate scatter plots. - It validates the provided configuration against the ScatterConfig schema, + It validates the provided configuration against the `ScatterConfig` schema, retrieves the appropriate plotting builder and saver functions based on the selected engine, builds the plot, and optionally saves it to a file. @@ -63,18 +63,11 @@ def create_scatter_plot( * **Python Script:** `docs/api_examples/scatter_plot.py` - https://github.com/Multiomics-Analytics-Group/vuecore/blob/main/docs/api_examples/scatter_plot.py """ - # 1. Validate configuration using Pydantic - config = ScatterConfig(**kwargs) - - # 2. Get the correct builder function from the registry - builder_func = get_builder(plot_type="scatter", engine=engine) - - # 3. Build the figure object (the API doesn't know or care what type it is) - figure = builder_func(data, config) - - # 4. Save the plot using the correct saver - if file_path: - saver_func = get_saver(engine=engine) - saver_func(figure, file_path) - - return figure + return create_plot( + data=data, + config=ScatterConfig, + plot_type=PlotType.SCATTER, + engine=engine, + file_path=file_path, + **kwargs, + ) diff --git a/src/vuecore/plots/plot_factory.py b/src/vuecore/plots/plot_factory.py new file mode 100644 index 0000000..62817de --- /dev/null +++ b/src/vuecore/plots/plot_factory.py @@ -0,0 +1,60 @@ +from typing import Any, Type +import pandas as pd +from vuecore import EngineType, PlotType +from vuecore.engines import get_builder, get_saver +from pydantic import BaseModel + + +def create_plot( + data: pd.DataFrame, + config: Type[BaseModel], + plot_type: PlotType, + engine: EngineType = EngineType.PLOTLY, + file_path: str = None, + **kwargs, +) -> Any: + """ + Factory function to create, style, and optionally save plots. + + This function handles the common workflow for creating plots: + 1. Validate configuration using the provided Pydantic model + 2. Get the appropriate builder function from the engine registry + 3. Build the figure using the builder + 4. Optionally save the plot if a file path is provided + + Parameters + ---------- + data : pd.DataFrame + The DataFrame containing the data to be plotted. + config : Type[BaseModel] + The Pydantic config class for validation. + plot_type : PlotType + The plot type from the `PlotType` enum (e.g., PlotType.BAR, PlotType.BOX, etc). + engine : EngineType, optional + The plotting engine to use for rendering the plot. + Defaults to `EngineType.PLOTLY`. + file_path : str, optional + If provided, the path where the final plot will be saved. + **kwargs + Keyword arguments for plot configuration. + + Returns + ------- + Any + The final plot object returned by the selected engine. + """ + # 1. Validate configuration using Pydantic + config = config(**kwargs) + + # 2. Get the correct builder function from the registry + builder_func = get_builder(plot_type=plot_type, engine=engine) + + # 3. Build the figure object + figure = builder_func(data, config) + + # 4. Save the plot using the correct saver function, if a file_path is provided + if file_path: + saver_func = get_saver(engine=engine) + saver_func(figure, file_path) + + return figure