Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
366 changes: 0 additions & 366 deletions docs/api_examples/box_plot.ipynb

This file was deleted.

4,426 changes: 4,426 additions & 0 deletions docs/api_examples/box_violin_plot.ipynb

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# ---

# %% [markdown]
# # Box Plot
# # Box and Violin Plots
#
# ![VueCore logo][vuecore_logo]
#
Expand All @@ -22,15 +22,17 @@
# [VueCore][vuecore_repo] is a Python package for creating interactive and static visualizations of multi-omics data.
# It is part of a broader ecosystem of tools—including [ACore][acore_repo] for data processing and [VueGen][vuegen_repo] for automated reporting—that together enable end-to-end workflows for omics analysis.
#
# This notebook demonstrates how to generate box plots using plotting functions from VueCore. We showcase basic and advanced plot configurations, highlighting key customization options such as grouping, color mapping, text annotations, and export to multiple file formats.
# This notebook demonstrates how to generate box and violin plots using plotting functions from VueCore. We showcase basic and advanced plot configurations, highlighting key customization options such as grouping, color mapping, text annotations, and export to multiple file formats.
#
# ## Notebook structure
#
# First, we will set up the work environment by installing the necessary packages and importing the required libraries. Next, we will create basic and advanced box plots.
#
# 0. [Work environment setup](#0-work-environment-setup)
# 1. [Basic box plot](#1-basic-box-plot)
# 2. [Advanced box plot](#2-advanced-box-plot)
# 2. [Basic violin plot](#2-basic-violin-plot)
# 3. [Advanced box plot](#3-advanced-box-plot)
# 4. [Advanced violin plot](#3-advanced-violin-plot)
#
# ## Credits and Contributors
# - This notebook was created by Sebastián Ayala-Ruano under the supervision of Henry Webel and Alberto Santos, head of the [Multiomics Network Analytics Group (MoNA)][Mona] at the [Novo Nordisk Foundation Center for Biosustainability (DTU Biosustain)][Biosustain].
Expand Down Expand Up @@ -75,8 +77,13 @@
import pandas as pd
import numpy as np
from pathlib import Path
import plotly.io as pio

from vuecore.plots.basic.box import create_box_plot
from vuecore.plots.basic.violin import create_violin_plot

# Set the Plotly renderer based on the environment
pio.renderers.default = "notebook"

# %% [markdown]
# ### 0.3. Create sample data
Expand Down Expand Up @@ -127,27 +134,46 @@
# A basic box plot can be created by simply providing the `x` and `y` columns from the DataFrame, along with style options like `title`.

# %%
# Define output file path for the PNG plot
file_path_basic_png = Path(output_dir) / "box_plot_basic.png"
# Define output file path for the PNG basic box plot
file_path_basic_box_png = Path(output_dir) / "box_plot_basic.png"

# Generate the basic box plot
box_plot_basic = create_box_plot(
data=gene_exp_df,
x="Treatment",
y="Expression",
title="Gene Expression Levels by Treatment",
file_path=file_path_basic_png,
file_path=file_path_basic_box_png,
)

box_plot_basic.show()

# %% [markdown]
# ## 2. Advanced Box Plot
# ## 2. Basic Violin Plot
# A basic violin plot can be created by simply providing the `x` and `y` columns from the DataFrame, along with style options like `title`.

# %%
# Define output file path for the PNG basic violin plot
file_path_basic_violin_png = Path(output_dir) / "violin_plot_basic.png"

# Generate the basic violin plot
violin_plot_basic = create_violin_plot(
data=gene_exp_df,
x="Treatment",
y="Expression",
title="Gene Expression Levels by Treatment",
file_path=file_path_basic_violin_png,
)

violin_plot_basic.show()

# %% [markdown]
# ## 3. Advanced Box Plot
# Here is an example of an advanced box plot with more descriptive parameters, including `color and box grouping`, `text annotations`, `hover tooltips`, and export to `HTML`.

# %%
# Define the output file path for the advanced HTML plot
file_path_adv_html = Path(output_dir) / "box_plot_advanced.html"
# Define the output file path for the advanced HTML box plot
file_path_adv_box_html = Path(output_dir) / "box_plot_advanced.html"

# Generate the advanced box plot
box_plot_adv = create_box_plot(
Expand All @@ -172,7 +198,43 @@
},
category_orders={"Sample_ID": ["Patient A", "Patient B", "Patient C", "Patient D"]},
hover_data=["Gene_ID"],
file_path=file_path_adv_html,
file_path=file_path_adv_box_html,
)

box_plot_adv.show()

# %% [markdown]
# ## 4. Advanced Violin Plot
# Here is an example of an advanced violin plot with more descriptive parameters, including `color and box grouping`, `text annotations`, `hover tooltips`, and export to `HTML`.

# %%
# Define the output file path for the advanced HTML violin plot
file_path_adv_violin_html = Path(output_dir) / "violin_plot_advanced.html"

# Generate the advanced box plot
violin_plot_adv = create_violin_plot(
data=gene_exp_df,
x="Treatment",
y="Expression",
color="Sample_ID",
violinmode="group",
points="outliers",
title="Gene Expression Levels with Control and Treatment Condition",
subtitle="Distribution of gene expression across different treatments and patient samples",
labels={
"Treatment": "Treatment",
"Expression": "Gene Expression",
"Sample_ID": "Patient Sample ID",
},
color_discrete_map={
"Patient A": "#508AA8",
"Patient B": "#A8505E",
"Patient C": "#86BF84",
"Patient D": "#A776AF",
},
category_orders={"Sample_ID": ["Patient A", "Patient B", "Patient C", "Patient D"]},
hover_data=["Gene_ID"],
file_path=file_path_adv_violin_html,
)

violin_plot_adv.show()
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ sections_readme/license
api_examples/scatter_plot
api_examples/line_plot
api_examples/bar_plot
api_examples/box_plot
api_examples/box_violin_plot
```

```{toctree}
Expand Down
1 change: 1 addition & 0 deletions src/vuecore/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class PlotType(StrEnum):
LINE = auto()
BAR = auto()
BOX = auto()
VIOLIN = auto()


class EngineType(StrEnum):
Expand Down
2 changes: 2 additions & 0 deletions src/vuecore/engines/plotly/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .line import build as build_line
from .bar import build as build_bar
from .box import build as build_box
from .violin import build as build_violin
from .saver import save

# Import build_utils to ensure it's available
Expand All @@ -17,5 +18,6 @@
register_builder(plot_type=PlotType.LINE, engine=EngineType.PLOTLY, func=build_line)
register_builder(plot_type=PlotType.BAR, engine=EngineType.PLOTLY, func=build_bar)
register_builder(plot_type=PlotType.BOX, engine=EngineType.PLOTLY, func=build_box)
register_builder(plot_type=PlotType.VIOLIN, engine=EngineType.PLOTLY, func=build_violin)

register_saver(engine=EngineType.PLOTLY, func=save)
33 changes: 33 additions & 0 deletions src/vuecore/engines/plotly/theming.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from vuecore.schemas.basic.line import LineConfig
from vuecore.schemas.basic.bar import BarConfig
from vuecore.schemas.basic.box import BoxConfig
from vuecore.schemas.basic.violin import ViolinConfig


def _get_axis_title(config, axis: str) -> str:
Expand Down Expand Up @@ -213,3 +214,35 @@ def apply_box_theme(fig: go.Figure, config: BoxConfig) -> go.Figure:
fig = _apply_common_layout(fig, config)

return fig


def apply_violin_theme(fig: go.Figure, config: ViolinConfig) -> go.Figure:
"""
Applies a consistent layout and theme to a Plotly violin plot.

This function handles all styling and layout adjustments, such as titles,
dimensions, templates, and trace properties, separating these concerns
from the initial data mapping.

Parameters
----------
fig : go.Figure
The Plotly figure object to be styled.
config : ViolinConfig
The configuration object containing all styling and layout info.

Returns
-------
go.Figure
The styled Plotly figure object.
"""
# Convert the box boolean parameter from the config to the go.Figure expected format
box_dict = {"visible": config.box}

# Apply trace-specific updates for violin plots
fig.update_traces(points=config.points, box=box_dict, selector=dict(type="violin"))

# Apply common layout
fig = _apply_common_layout(fig, config)

return fig
57 changes: 57 additions & 0 deletions src/vuecore/engines/plotly/violin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

from vuecore.schemas.basic.violin import ViolinConfig
from .theming import apply_violin_theme
from .plot_builder import build_plot

# Define parameters handled by the theme script
THEMING_PARAMS = [
"violinmode",
"log_x",
"log_y",
"range_x",
"range_y",
"points",
"box",
"title",
"x_title",
"y_title",
"subtitle",
"template",
"width",
"height",
]


def build(data: pd.DataFrame, config: ViolinConfig) -> go.Figure:
"""
Creates a Plotly violin plot figure from a DataFrame and a Pydantic configuration.

This function acts as a bridge between the abstract plot definition and the
Plotly Express implementation. It translates the validated `ViolinConfig`
into the arguments for `plotly.express.violin` and also forwards any
additional, unvalidated keyword arguments from Plotly. The resulting figure
is then customized with layout and theme settings using `plotly.graph_objects`.
(https://plotly.com/python-api-reference/generated/plotly.express.violin.html).

Parameters
----------
data : pd.DataFrame
The DataFrame containing the plot data.
config : ViolinConfig
The validated Pydantic model with all plot configurations.

Returns
-------
go.Figure
A `plotly.graph_objects.Figure` object representing the violin plot.
"""
return build_plot(
data=data,
config=config,
px_function=px.violin,
theming_function=apply_violin_theme,
theming_params=THEMING_PARAMS,
)
8 changes: 4 additions & 4 deletions src/vuecore/plots/basic/box.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ def create_box_plot(
--------
For detailed examples and usage, please refer to the documentation:

* **Jupyter Notebook:** `docs/api_examples/box_plot.ipynb` -
https://vuecore.readthedocs.io/en/latest/api_examples/box_plot.html
* **Python Script:** `docs/api_examples/box_plot.py` -
https://github.com/Multiomics-Analytics-Group/vuecore/blob/main/docs/api_examples/box_plot.py
* **Jupyter Notebook:** `docs/api_examples/box_violin_plot.ipynb` -
https://vuecore.readthedocs.io/en/latest/api_examples/box_violin_plot.html
* **Python Script:** `docs/api_examples/box_violin_plot.py` -
https://github.com/Multiomics-Analytics-Group/vuecore/blob/main/docs/api_examples/box_violin_plot.py
"""
return create_plot(
data=data,
Expand Down
73 changes: 73 additions & 0 deletions src/vuecore/plots/basic/violin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from typing import Any

import pandas as pd

from vuecore import EngineType, PlotType
from vuecore.schemas.basic.violin import ViolinConfig
from vuecore.plots.plot_factory import create_plot
from vuecore.utils.docs_utils import document_pydant_params


@document_pydant_params(ViolinConfig)
def create_violin_plot(
data: pd.DataFrame,
engine: EngineType = EngineType.PLOTLY,
file_path: str = None,
**kwargs,
) -> Any:
"""
Creates, styles, and optionally saves a violin plot using the specified engine.

This function serves as the main entry point for users to generate violin plots.
It validates the provided configuration against the `ViolinConfig` schema,
retrieves the appropriate plotting builder and saver functions based on the
selected engine, builds the plot, and optionally saves it to a file.

Parameters
----------
data : pd.DataFrame
The DataFrame containing the data to be plotted. Each row represents
an observation, and columns correspond to variables.
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.
The file format is automatically inferred from the file extension
(e.g., '.html', '.png', '.jpeg', '.svg'). Defaults to None, meaning
the plot will not be saved.

Returns
-------
Any
The final plot object returned by the selected engine.
For Plotly, this will typically be a `plotly.graph_objects.Figure`.
The exact type depends on the chosen engine.

Raises
------
pydantic.ValidationError
If the provided keyword arguments do not conform to the `ViolinConfig` schema.
e.g., a required parameter is missing or a value has an incorrect type.
ValueError
Raised by the plotting engine (e.g., Plotly Express) if a
column specified in the configuration (e.g., 'x', 'y', 'color') is
not found in the provided DataFrame.

Examples
--------
For detailed examples and usage, please refer to the documentation:

* **Jupyter Notebook:** `docs/api_examples/box_violin_plot.ipynb` -
https://vuecore.readthedocs.io/en/latest/api_examples/box_violin_plot.html
* **Python Script:** `docs/api_examples/box_violin_plot.py` -
https://github.com/Multiomics-Analytics-Group/vuecore/blob/main/docs/api_examples/box_violin_plot.py
"""
return create_plot(
data=data,
config=ViolinConfig,
plot_type=PlotType.VIOLIN,
engine=engine,
file_path=file_path,
**kwargs,
)
Loading