Skip to content

Commit 4029150

Browse files
authored
✨ Create Base Plotly Schema (#31)
* ✨ Feat(vuecore/schemas/plotly_base.py): Create base plotly config for pydantic models to store parameters shared across multiple plot types * 🎨 Format(vuecore/schemas/basic/bar.py): Update bar pydantic model, extending from PlotlyBaseConfig to reduce code repetition * 🎨 Format(vuecore/schemas/basic/box.py): Update box pydantic model, extending from PlotlyBaseConfig to reduce code repetition * 🎨 Format(vuecore/schemas/basic/line.py): Update line pydantic model, extending from PlotlyBaseConfig to reduce code repetition * 🎨 Format(vuecore/schemas/basic/scatter.py): Update scatter pydantic model, extending from PlotlyBaseConfig to reduce code repetition * ➕ Format(vuecore/schemas/basic/scatter.py):Correct dependencies * ✨ Feat(src/vuecore/utils/__init__.py): add combine_docstrings decorator to combine a class's docstring with its parent's docstring * ✨ Feat: add combine_docstrings decorator to the bar, box, scatter, and line plots * 🐛 Fix(src/vuecore/utils/__init__.py): use dedent on parent and child attributes to ensure correct format * 🐛 Fix(docs/conf.py): add autodoc configiration to avoid duplicate Pydantic fields * 🐛 Fix(docs/conf.py): set autodoc_typehints to none and avoid Napoleon’s auto-parameters * 🐛 Fix(docs/conf.py): Set no-members and no-inherited-members from autodoc_default_options dict to True to avoid duplicate attributes * 🐛 Fix(docs/conf.py): Try autodoc_pydantic extension t ahndle pydantic attributes * 🐛 Fix(.readthedocs.yaml): fix nltk build error by downloading the corpora during the RTD build * 🐛 Fix(docs/conf.py): load NLTK stopwords in the conf.py to avoid build error * 🐛 Fix(docs/conf.py): add extra parameters to fix duplicated attributes * ⏪️ Revert changes on conf.py bc autodoc_pydantic did not fix the duplicated attributes problem * 🐛 Fix(docs/conf.py): add autodoc_default_options options to avoid duplicated attributes * 🐛 Fix(docs/conf.py): Add event handler to avoid duplicate attributes * ⏪️ Revert change of event handler * 🎨 Style: fix indentation issue with docstrings and remove extra dashes * ⏪️ Revert combine_docstring decorator change * 🔥 Remove manual docstrings attributes from Pydantic schemas * ✨ Feat: Use autodoc_pydantic sphinx extension to show the pydantic docstrings * 🎨 Add __init__.py file on the src/vuecore/plots folder to make it visible on the sphinx docs * ✨ Feat(vuecore/utils/docs_utils.py): create document_pydant_params decorator and helper functions to add Pydantic model parameters into a docsting of a target function * ✨ Feat: add the document_pydant_params decorator in all plot scripts * 🎨 Format(vuecore/utils/docs_utils.py): add new line in description of document_pydant_params decorator * ✅ Feat(tests/test_docs_utils.py): add tests for the docs_utils script * 🐛 Fix(src/vuecore/utils/docs_utils.py): remove f on list of strings * ✅ Feat: update main test in the tests/test_docs_utils.py file * 🐛 Fix(src/vuecore/utils/docs_utils.py): removeunnecesary fstring in one of the elemnts of the list to avoid ruff issue
1 parent ca7f2eb commit 4029150

File tree

16 files changed

+399
-446
lines changed

16 files changed

+399
-446
lines changed

docs/conf.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
# list see the documentation:
55
# https://www.sphinx-doc.org/en/master/usage/configuration.html
66

7+
import nltk
8+
9+
# Make sure stopwords are available for autodoc
10+
try:
11+
nltk.data.find("corpora/stopwords")
12+
except LookupError:
13+
nltk.download("stopwords")
14+
715
# -- Path setup --------------------------------------------------------------
816

917
# If extensions (or modules to document with autodoc) are in another directory,
@@ -27,7 +35,6 @@
2735

2836

2937
# -- General configuration ---------------------------------------------------
30-
3138
# Add any Sphinx extension module names here, as strings. They can be
3239
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
3340
# ones.
@@ -40,6 +47,7 @@
4047
"sphinx_new_tab_link",
4148
"myst_nb",
4249
"sphinx_copybutton",
50+
"sphinxcontrib.autodoc_pydantic",
4351
]
4452

4553
# https://myst-nb.readthedocs.io/en/latest/computation/execute.html
@@ -81,7 +89,6 @@
8189
"conf.py",
8290
]
8391

84-
8592
# Intersphinx options
8693
intersphinx_mapping = {
8794
"python": ("https://docs.python.org/3", None),
@@ -93,6 +100,30 @@
93100
"numpy": ("https://numpy.org/doc/stable/", None),
94101
}
95102

103+
# Options for the autodoc_pydantic extension
104+
autodoc_pydantic_field_show_default = True
105+
autodoc_pydantic_field_show_constraints = True
106+
autodoc_pydantic_field_list_validators = True
107+
autodoc_pydantic_model_signature_prefix = "class"
108+
autodoc_pydantic_field_signature_prefix = "attribute"
109+
autodoc_pydantic_field_show_required = True
110+
autodoc_pydantic_field_show_optional = True
111+
autodoc_pydantic_field_show_default = True
112+
autodoc_pydantic_field_doc_policy = "description"
113+
autodoc_pydantic_model_member_order = "bysource"
114+
autodoc_pydantic_model_show_json = False
115+
autodoc_pydantic_model_show_field_summary = False
116+
autodoc_pydantic_model_show_config_summary = False
117+
autodoc_pydantic_model_show_validator_summary = False
118+
autodoc_pydantic_model_hide_paramlist = False
119+
autodoc_pydantic_field_list_validators = False
120+
121+
# Options for the autodoc extension
122+
autodoc_default_options = {
123+
"inherited-members": "BaseModel",
124+
"show-inheritance": True,
125+
}
126+
96127
# -- Options for HTML output -------------------------------------------------
97128

98129
# The theme to use for HTML and HTML Help pages. See the documentation for

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ docs = [
5353
"sphinx-new-tab-link!=0.2.2",
5454
"jupytext",
5555
"sphinx-copybutton",
56+
"autodoc_pydantic",
5657
]
5758
dev = [
5859
"black",

src/vuecore/plots/__init__.py

Whitespace-only changes.

src/vuecore/plots/basic/bar.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
from vuecore import EngineType
66
from vuecore.engines import get_builder, get_saver
77
from vuecore.schemas.basic.bar import BarConfig
8+
from vuecore.utils.docs_utils import document_pydant_params
89

910

11+
@document_pydant_params(BarConfig)
1012
def create_bar_plot(
1113
data: pd.DataFrame,
1214
engine: EngineType = EngineType.PLOTLY,
@@ -34,11 +36,6 @@ def create_bar_plot(
3436
The file format is automatically inferred from the file extension
3537
(e.g., '.html', '.png', '.jpeg', '.svg'). Defaults to None, meaning
3638
the plot will not be saved.
37-
**kwargs
38-
Keyword arguments for plot configuration. These arguments are
39-
validated against the `BarConfig` Pydantic model. Refer to
40-
`vuecore.schemas.basic.bar.BarConfig` for all available
41-
options and their descriptions.
4239
4340
Returns
4441
-------

src/vuecore/plots/basic/box.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
from vuecore import EngineType
66
from vuecore.engines import get_builder, get_saver
77
from vuecore.schemas.basic.box import BoxConfig
8+
from vuecore.utils.docs_utils import document_pydant_params
89

910

11+
@document_pydant_params(BoxConfig)
1012
def create_box_plot(
1113
data: pd.DataFrame,
1214
engine: EngineType = EngineType.PLOTLY,
@@ -34,11 +36,6 @@ def create_box_plot(
3436
The file format is automatically inferred from the file extension
3537
(e.g., '.html', '.png', '.jpeg', '.svg'). Defaults to None, meaning
3638
the plot will not be saved.
37-
**kwargs
38-
Keyword arguments for plot configuration. These arguments are
39-
validated against the `BoxConfig` Pydantic model. Refer to
40-
`vuecore.schemas.basic.box.BoxConfig` for all available
41-
options and their descriptions.
4239
4340
Returns
4441
-------

src/vuecore/plots/basic/line.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
from vuecore import EngineType
66
from vuecore.engines import get_builder, get_saver
77
from vuecore.schemas.basic.line import LineConfig
8+
from vuecore.utils.docs_utils import document_pydant_params
89

910

11+
@document_pydant_params(LineConfig)
1012
def create_line_plot(
1113
data: pd.DataFrame,
1214
engine: EngineType = EngineType.PLOTLY,
@@ -34,10 +36,6 @@ def create_line_plot(
3436
The file format is automatically inferred from the file extension
3537
(e.g., '.html', '.png', '.jpeg', '.svg'). Defaults to None, meaning
3638
the plot will not be saved.
37-
**kwargs
38-
Keyword arguments for plot configuration. These arguments are validated
39-
against the `LineConfig` Pydantic model. See
40-
`vuecore.schemas.basic.line.LineConfig` for all available options.
4139
4240
Returns
4341
-------

src/vuecore/plots/basic/scatter.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
from vuecore import EngineType
66
from vuecore.engines import get_builder, get_saver
77
from vuecore.schemas.basic.scatter import ScatterConfig
8+
from vuecore.utils.docs_utils import document_pydant_params
89

910

11+
@document_pydant_params(ScatterConfig)
1012
def create_scatter_plot(
1113
data: pd.DataFrame,
1214
engine: EngineType = EngineType.PLOTLY,
@@ -34,10 +36,6 @@ def create_scatter_plot(
3436
The file format is automatically inferred from the file extension
3537
(e.g., '.html', '.png', '.jpeg', '.svg'). Defaults to None, meaning
3638
the plot will not be saved.
37-
**kwargs
38-
Keyword arguments for plot configuration. These arguments are validated
39-
against the `ScatterConfig` Pydantic model. See
40-
`schemas.basic.scatter.ScatterConfig` for all available options.
4139
4240
Returns
4341
-------

src/vuecore/schemas/__init__.py

Whitespace-only changes.

src/vuecore/schemas/basic/bar.py

Lines changed: 6 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
from typing import Dict, List, Optional
2-
from pydantic import BaseModel, Field, ConfigDict
1+
from typing import Dict, Optional
2+
from pydantic import Field, ConfigDict
3+
from vuecore.schemas.plotly_base import PlotlyBaseConfig
34

45

5-
class BarConfig(BaseModel):
6+
class BarConfig(PlotlyBaseConfig):
67
"""
7-
Pydantic model for validating and managing bar plot configurations.
8+
Pydantic model for validating and managing bar plot configurations,
9+
which extends PlotlyBaseConfig.
810
911
This model serves as a curated API for the most relevant parameters
1012
for bar plots, closely aligned with the `plotly.express.bar` API
@@ -16,101 +18,19 @@ class BarConfig(BaseModel):
1618
defined here, and also accepts additional Plotly keyword arguments,
1719
forwarding them to the appropriate `plotly.express.bar` or
1820
`plotly.graph_objects.Figure` call.
19-
20-
Attributes
21-
----------
22-
-----Data Mapping-----
23-
x : str
24-
Column for the x-axis values.
25-
y : str
26-
Column for the y-axis values.
27-
color : Optional[str]
28-
Column to assign color to bars.
29-
pattern_shape : Optional[str]
30-
Column to assign pattern shapes to bars.
31-
hover_name : Optional[str]
32-
Column to appear in bold in the hover tooltip.
33-
hover_data : Optional[List[str]]
34-
Additional columns to display in the hover tooltip.
35-
text : Optional[str]
36-
Column for adding text labels to bars.
37-
facet_row : Optional[str]
38-
Column to create vertical subplots (facets).
39-
facet_col : Optional[str]
40-
Column to create horizontal subplots (facets).
41-
error_x : Optional[str]
42-
Column for sizing x-axis error bars.
43-
error_y : Optional[str]
44-
Column for sizing y-axis error bars.
45-
labels : Optional[Dict[str, str]]
46-
Dictionary to override column names for titles, legends, etc.
47-
color_discrete_map : Optional[Dict[str, str]]
48-
Specific color mappings for values in the `color` column.
49-
pattern_shape_map : Optional[Dict[str, str]]
50-
Specific pattern shape mappings for values in the `pattern_shape` column.
51-
-----Styling and Layout-----
52-
opacity : float
53-
Marker opacity (0-1).
54-
orientation: str
55-
Orientation of the bars ('v' for vertical, 'h' for horizontal).
56-
barmode : str
57-
Mode for grouping bars ('group', 'overlay', 'relative').
58-
log_x : bool
59-
If True, the x-axis is log-scaled.
60-
log_y : bool
61-
If True, the y-axis is log-scaled.
62-
range_x : Optional[List[float]]
63-
Range for the x-axis, e.g., [0, 100].
64-
range_y : Optional[List[float]]
65-
Range for the y-axis, e.g., [0, 100].
66-
title : str
67-
The main title of the plot.
68-
x_title : Optional[str]
69-
Custom title for the x-axis.
70-
y_title : Optional[str]
71-
Custom title for the y-axis.
72-
subtitle : str
73-
The subtitle of the plot.
74-
template : str
75-
Plotly template for styling (e.g., 'plotly_white').
76-
width : int
77-
Width of the plot in pixels.
78-
height : int
79-
Height of the plot in pixels.
8021
"""
8122

8223
# General Configuration
8324
# Allow extra parameters to pass through to Plotly
8425
model_config = ConfigDict(extra="allow")
8526

8627
# Data Mapping
87-
x: str = Field(..., description="Column for x-axis values.")
88-
y: str = Field(..., description="Column for y-axis values.")
89-
color: Optional[str] = Field(None, description="Column to assign color to bars.")
9028
pattern_shape: Optional[str] = Field(
9129
None, description="Column to assign pattern shapes to bars."
9230
)
93-
hover_name: Optional[str] = Field(
94-
None, description="Column for bold text in hover tooltip."
95-
)
96-
hover_data: List[str] = Field(
97-
[], description="Additional columns for the hover tooltip."
98-
)
9931
text: Optional[str] = Field(None, description="Column for text labels on bars.")
100-
facet_row: Optional[str] = Field(
101-
None, description="Column to create vertical subplots."
102-
)
103-
facet_col: Optional[str] = Field(
104-
None, description="Column to create horizontal subplots."
105-
)
10632
error_x: Optional[str] = Field(None, description="Column for x-axis error bars.")
10733
error_y: Optional[str] = Field(None, description="Column for y-axis error bars.")
108-
labels: Optional[Dict[str, str]] = Field(
109-
None, description="Override column names in the plot."
110-
)
111-
color_discrete_map: Optional[Dict[str, str]] = Field(
112-
None, description="Map values to specific colors."
113-
)
11434
pattern_shape_map: Optional[Dict[str, str]] = Field(
11535
None, description="Map values to specific pattern shapes."
11636
)
@@ -122,18 +42,3 @@ class BarConfig(BaseModel):
12242
description="Orientation of the bars ('v' for vertical, 'h' for horizontal).",
12343
)
12444
barmode: str = Field("relative", description="Mode for grouping bars.")
125-
log_x: bool = Field(False, description="If True, use a logarithmic x-axis.")
126-
log_y: bool = Field(False, description="If True, use a logarithmic y-axis.")
127-
range_x: Optional[List[float]] = Field(
128-
None, description="Range for the x-axis, e.g., [0, 100]."
129-
)
130-
range_y: Optional[List[float]] = Field(
131-
None, description="Range for the y-axis, e.g., [0, 100]."
132-
)
133-
title: str = Field("Bar Plot", description="The main title of the plot.")
134-
x_title: Optional[str] = Field(None, description="Custom title for the x-axis.")
135-
y_title: Optional[str] = Field(None, description="Custom title for the y-axis.")
136-
subtitle: Optional[str] = Field(None, description="The subtitle for the plot.")
137-
template: str = Field("plotly_white", description="Plotly template for styling.")
138-
width: int = Field(800, description="Width of the plot in pixels.")
139-
height: int = Field(600, description="Height of the plot in pixels.")

0 commit comments

Comments
 (0)